| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import { Colors } from "@/constants/Colors"; // Import Colors
- import { Images } from "@/constants/images";
- import { Image } from "expo-image";
- import { usePathname, useRouter, useSegments } from "expo-router";
- import React from "react";
- import {
- Dimensions,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
- } from "react-native";
- import { useSafeAreaInsets } from "react-native-safe-area-context";
- const { width: SCREEN_WIDTH } = Dimensions.get("window");
- const tabList = [
- {
- name: "大厅", // Was 首页
- route: "/",
- img: Images.tabs.home,
- active: Images.tabs.homeActive,
- },
- {
- name: "矩阵", // Was 开箱
- route: "/box",
- img: Images.tabs.box,
- active: Images.tabs.boxActive,
- },
- {
- name: "次元", // Was 福利
- route: "/dimension",
- img: Images.tabs.welfare,
- active: Images.tabs.welfareActive,
- },
- {
- name: "档案", // Was 我的
- 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 Dimension (formerly Welfare)
- if (
- (segments[1] as string) === "dimension" ||
- pathname?.startsWith("/dimension")
- )
- return 2;
- // Check Mine
- if (segments[1] === "mine" || pathname?.startsWith("/mine")) return 3;
- // Check Home (Explicit)
- if (
- (segments[1] as string) === "index" ||
- pathname === "/" ||
- pathname === "/index"
- )
- return 0;
- return -1;
- };
- const [currentIndex, setCurrentIndex] = React.useState(() => {
- const idx = getTabIndex();
- return idx === -1 ? 0 : idx;
- });
- 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);
- };
- return (
- <View style={styles.wrapper}>
- {/* Replaced ImageBackground with View for Cyberpunk style */}
- <View style={styles.container}>
- <View style={styles.center}>
- {tabList.map((item, index) => {
- const isActive = currentIndex === index;
- return (
- <TouchableOpacity
- key={index}
- style={styles.item}
- activeOpacity={0.8}
- onPress={() => handlePress(index)}
- >
- <View
- style={[
- styles.iconContainer,
- isActive && styles.activeIconContainer,
- ]}
- >
- <Image
- source={isActive ? item.active : item.img}
- style={styles.icon}
- contentFit="contain"
- />
- </View>
- <Text
- style={[
- styles.label,
- { color: isActive ? Colors.neonBlue : Colors.textTertiary },
- ]}
- >
- {item.name}
- </Text>
- </TouchableOpacity>
- );
- })}
- </View>
- </View>
- </View>
- );
- }
- const styles = StyleSheet.create({
- wrapper: {
- position: "absolute",
- bottom: 0,
- left: 0,
- right: 0,
- zIndex: 999,
- },
- container: {
- width: SCREEN_WIDTH,
- height: 85, // Slightly taller for labels
- backgroundColor: Colors.darkBg,
- borderTopWidth: 1,
- borderTopColor: Colors.neonBlue,
- borderTopLeftRadius: 20,
- borderTopRightRadius: 20,
- // Neon Glow
- shadowColor: Colors.neonBlue,
- shadowOffset: { width: 0, height: -2 },
- shadowOpacity: 0.3,
- shadowRadius: 10,
- elevation: 10,
- paddingBottom: 20, // For home indicator
- },
- center: {
- flex: 1,
- flexDirection: "row",
- alignItems: "center",
- },
- item: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- paddingTop: 10,
- },
- iconContainer: {
- width: 28,
- height: 28,
- marginBottom: 4,
- justifyContent: "center",
- alignItems: "center",
- },
- activeIconContainer: {
- // Optional: Add glow behind active icon
- },
- icon: {
- width: "100%",
- height: "100%",
- },
- label: {
- fontSize: 10,
- fontWeight: "bold",
- },
- });
|