feat: 重构项目并添加新功能
- 重命名项目为 Digital Pilates - 更新 bundleIdentifier 为 digital-pilates - 重新设计底部导航栏,增加选中状态和标签 - 添加 CLAUDE.md 文件,提供代码助手指导 - 删除 README.md 文件中的冗余信息
This commit is contained in:
@@ -1,43 +1,139 @@
|
||||
import { Tabs } from 'expo-router';
|
||||
import * as Haptics from 'expo-haptics';
|
||||
import { Tabs, usePathname } from 'expo-router';
|
||||
import React from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
import { HapticTab } from '@/components/HapticTab';
|
||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||
import TabBarBackground from '@/components/ui/TabBarBackground';
|
||||
import { Colors } from '@/constants/Colors';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
|
||||
export default function TabLayout() {
|
||||
const colorScheme = useColorScheme();
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
||||
headerShown: false,
|
||||
tabBarButton: HapticTab,
|
||||
tabBarBackground: TabBarBackground,
|
||||
tabBarStyle: Platform.select({
|
||||
ios: {
|
||||
// Use a transparent background on iOS to show the blur effect
|
||||
position: 'absolute',
|
||||
screenOptions={({ route }) => {
|
||||
const routeName = route.name;
|
||||
const isSelected = (routeName === 'index' && pathname === '/') ||
|
||||
(routeName === 'explore' && pathname === '/explore') ||
|
||||
pathname.includes(routeName);
|
||||
|
||||
return {
|
||||
tabBarActiveTintColor: '#192126',
|
||||
tabBarButton: (props) => {
|
||||
const { children, onPress } = props;
|
||||
|
||||
const handlePress = (event: any) => {
|
||||
if (process.env.EXPO_OS === 'ios') {
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||
}
|
||||
onPress && onPress(event);
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={handlePress}
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
marginHorizontal: 6,
|
||||
marginVertical: 10,
|
||||
borderRadius: 25,
|
||||
backgroundColor: isSelected ? '#BBF246' : 'transparent',
|
||||
paddingHorizontal: isSelected ? 24 : 12,
|
||||
paddingVertical: 8,
|
||||
minWidth: isSelected ? 140 : 48,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
default: {},
|
||||
}),
|
||||
tabBarStyle: {
|
||||
position: 'absolute',
|
||||
bottom: 20,
|
||||
height: 68,
|
||||
borderRadius: 34,
|
||||
backgroundColor: '#192126',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 10,
|
||||
elevation: 5,
|
||||
paddingHorizontal: 10,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
marginHorizontal: 20,
|
||||
width: '90%',
|
||||
alignSelf: 'center',
|
||||
},
|
||||
tabBarItemStyle: {
|
||||
backgroundColor: 'transparent',
|
||||
height: 68,
|
||||
marginTop: 0,
|
||||
marginBottom: 0,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
},
|
||||
tabBarShowLabel: false,
|
||||
};
|
||||
}}>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
title: 'Home',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
|
||||
tabBarIcon: ({ color }) => {
|
||||
const isHomeSelected = pathname === '/' || pathname === '/index';
|
||||
return (
|
||||
<View style={{ flexDirection: 'column', alignItems: 'center' }}>
|
||||
<IconSymbol size={22} name="house.fill" color={color} />
|
||||
{isHomeSelected && (
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={{
|
||||
color: color,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
marginTop: 4,
|
||||
textAlign: 'center',
|
||||
flexShrink: 0,
|
||||
minWidth: 60,
|
||||
}}>
|
||||
Home
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="explore"
|
||||
options={{
|
||||
title: 'Explore',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
|
||||
tabBarIcon: ({ color }) => {
|
||||
const isExploreSelected = pathname === '/explore';
|
||||
return (
|
||||
<View style={{ flexDirection: 'column', alignItems: 'center' }}>
|
||||
<IconSymbol size={22} name="paperplane.fill" color={color} />
|
||||
{isExploreSelected && (
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={{
|
||||
color: color,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
marginTop: 4,
|
||||
textAlign: 'center',
|
||||
flexShrink: 0,
|
||||
minWidth: 60,
|
||||
}}>
|
||||
Explore
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
Reference in New Issue
Block a user