CustomTabBar.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { Images } from '@/constants/images';
  2. import { Image } from 'expo-image';
  3. import { usePathname, useRouter } from 'expo-router';
  4. import React from 'react';
  5. import { Dimensions, ImageBackground, StyleSheet, TouchableOpacity, View } from 'react-native';
  6. import { useSafeAreaInsets } from 'react-native-safe-area-context';
  7. const { width: SCREEN_WIDTH } = Dimensions.get('window');
  8. const tabList = [
  9. {
  10. name: '首页',
  11. route: '/',
  12. img: Images.tabs.home,
  13. active: Images.tabs.homeActive,
  14. },
  15. {
  16. name: '开箱',
  17. route: '/box',
  18. img: Images.tabs.box,
  19. active: Images.tabs.boxActive,
  20. },
  21. {
  22. name: '福利',
  23. route: '/welfare',
  24. img: Images.tabs.welfare,
  25. active: Images.tabs.welfareActive,
  26. },
  27. {
  28. name: '我的',
  29. route: '/mine',
  30. img: Images.tabs.mine,
  31. active: Images.tabs.mineActive,
  32. },
  33. ];
  34. export function CustomTabBar() {
  35. const router = useRouter();
  36. const pathname = usePathname();
  37. const insets = useSafeAreaInsets();
  38. const getTabIndex = () => {
  39. if (pathname === '/' || pathname === '/index') return 0;
  40. if (pathname === '/box') return 1;
  41. if (pathname === '/welfare') return 2;
  42. if (pathname === '/mine') return 3;
  43. return 0;
  44. };
  45. const currentIndex = getTabIndex();
  46. const handlePress = (index: number) => {
  47. const route = tabList[index].route;
  48. router.replace(route as any);
  49. };
  50. // 计算底部安全区域高度
  51. const bottomPadding = insets.bottom;
  52. return (
  53. <View style={[styles.wrapper, { paddingBottom: bottomPadding }]}>
  54. <ImageBackground
  55. style={styles.container}
  56. resizeMode="cover"
  57. >
  58. <View style={styles.center}>
  59. {tabList.map((item, index) => (
  60. <TouchableOpacity
  61. key={index}
  62. style={styles.item}
  63. activeOpacity={0.8}
  64. onPress={() => handlePress(index)}
  65. >
  66. <Image
  67. source={currentIndex === index ? item.active : item.img}
  68. style={styles.icon}
  69. contentFit="contain"
  70. />
  71. </TouchableOpacity>
  72. ))}
  73. </View>
  74. </ImageBackground>
  75. </View>
  76. );
  77. }
  78. const styles = StyleSheet.create({
  79. wrapper: {
  80. position: 'absolute',
  81. bottom: 0,
  82. left: 0,
  83. right: 0,
  84. zIndex: 999,
  85. },
  86. container: {
  87. width: SCREEN_WIDTH,
  88. height: 78,
  89. },
  90. center: {
  91. flex: 1,
  92. flexDirection: 'row',
  93. },
  94. item: {
  95. flex: 1,
  96. justifyContent: 'center',
  97. alignItems: 'center',
  98. },
  99. icon: {
  100. width: '100%',
  101. height: '100%',
  102. },
  103. });