| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import { Images } from '@/constants/images';
- import { Image } from 'expo-image';
- import { usePathname, useRouter, useSegments } from 'expo-router';
- import React from 'react';
- import { Dimensions, ImageBackground, StyleSheet, TouchableOpacity, View } from 'react-native';
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
- const { width: SCREEN_WIDTH } = Dimensions.get('window');
- const tabList = [
- {
- name: '首页',
- route: '/',
- img: Images.tabs.home,
- active: Images.tabs.homeActive,
- },
- {
- name: '开箱',
- route: '/box',
- img: Images.tabs.box,
- active: Images.tabs.boxActive,
- },
- {
- name: '福利',
- route: '/welfare',
- img: Images.tabs.welfare,
- active: Images.tabs.welfareActive,
- },
- {
- name: '我的',
- route: '/mine',
- img: Images.tabs.mine,
- active: Images.tabs.mineActive,
- },
- ];
- export function CustomTabBar() {
- const router = useRouter();
- const segments = useSegments();
- const pathname = usePathname();
- const insets = useSafeAreaInsets();
- const getTabIndex = () => {
- // Check Box
- if (segments[1] === 'box' || pathname?.startsWith('/box')) return 1;
- // Check Welfare
- if (segments[1] === 'welfare' || pathname?.startsWith('/welfare')) return 2;
- // Check Mine
- if (segments[1] === 'mine' || pathname?.startsWith('/mine')) return 3;
-
- // Check Home (Explicit)
- // Home is usually index. or path /
- if (segments[1] === 'index' || pathname === '/' || pathname === '/index') return 0;
- // No valid tab match (e.g. navigating to detail page)
- return -1;
- };
- // Initialize with correct value to avoid mount flash
- const [currentIndex, setCurrentIndex] = React.useState(() => {
- const idx = getTabIndex();
- return idx === -1 ? 0 : idx;
- });
- // Update only when valid match found (avoids unmatch flash)
- React.useEffect(() => {
- const idx = getTabIndex();
- if (idx !== -1) {
- setCurrentIndex(idx);
- }
- }, [segments, pathname]);
- const handlePress = (index: number) => {
- const route = tabList[index].route;
- router.replace(route as any);
- };
- // 计算底部安全区域高度
- const bottomPadding = insets.bottom;
- return (
- <View style={styles.wrapper}>
- <ImageBackground
- source={{ uri: Images.common.kaixinTabbarBg }}
- style={styles.container}
- resizeMode="stretch"
- >
- <View style={styles.center}>
- {tabList.map((item, index) => (
- <TouchableOpacity
- key={index}
- style={styles.item}
- activeOpacity={0.8}
- onPress={() => handlePress(index)}
- >
- <Image
- source={currentIndex === index ? item.active : item.img}
- style={styles.icon}
- contentFit="fill"
- />
- </TouchableOpacity>
- ))}
- </View>
- </ImageBackground>
- </View>
- );
- }
- const styles = StyleSheet.create({
- wrapper: {
- position: 'absolute',
- bottom: 0,
- left: 0,
- right: 0,
- zIndex: 999,
- },
- container: {
- width: SCREEN_WIDTH,
- height: 78,
- },
- center: {
- flex: 1,
- flexDirection: 'row',
- },
- item: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- },
- icon: {
- width: '100%',
- height: '100%',
- },
- });
|