如何在React Native中创建带圆角和内嵌背景的Bottom Tab Navigator?
针对你需要的这种中间Tab凸起的底部导航栏,以下是基于React Navigation的具体实现方案,完全自定义样式来匹配需求:
1. 安装依赖
确保你已经安装了核心导航库和相关依赖:
npm install @react-navigation/native @react-navigation/bottom-tabs react-native-screens react-native-safe-area-context react-native-svg
2. 自定义Tab Bar组件
核心是完全自定义TabBar组件,替代默认的底部导航栏,实现中间Tab的凸起效果:
import React from 'react'; import { View, TouchableOpacity, Text, StyleSheet } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; const CustomTabBar = ({ state, descriptors, navigation }) => { return ( <View style={styles.tabBarContainer}> {state.routes.map((route, index) => { const { options } = descriptors[route.key]; const label = options.tabBarLabel !== undefined ? options.tabBarLabel : options.title !== undefined ? options.title : route.name; const isFocused = state.index === index; const isMiddleTab = index === 2; // 假设中间Tab是第3个(索引从0开始) const onPress = () => { const event = navigation.emit({ type: 'tabPress', target: route.key, canPreventDefault: true, }); if (!isFocused && !event.defaultPrevented) { navigation.navigate(route.name); } }; const onLongPress = () => { navigation.emit({ type: 'tabLongPress', target: route.key, }); }; return ( <TouchableOpacity key={route.key} accessibilityRole="button" accessibilityState={isFocused ? { selected: true } : {}} accessibilityLabel={options.tabBarAccessibilityLabel} testID={options.tabBarTestID} onPress={onPress} onLongPress={onLongPress} style={[ styles.tabItem, isMiddleTab && styles.middleTabItem, ]} > <View style={[ styles.iconContainer, isMiddleTab && styles.middleIconContainer, isFocused && styles.focusedIconContainer ]}> <Ionicons name={isFocused ? options.tabBarIcon.focused : options.tabBarIcon.unfocused} size={isMiddleTab ? 28 : 24} color={isFocused ? '#2563eb' : '#6b7280'} /> </View> {!isMiddleTab && ( <Text style={[ styles.tabLabel, isFocused && styles.focusedTabLabel ]}> {label} </Text> )} </TouchableOpacity> ); })} </View> ); }; const styles = StyleSheet.create({ tabBarContainer: { flexDirection: 'row', backgroundColor: '#ffffff', borderTopWidth: 1, borderTopColor: '#e5e7eb', paddingVertical: 8, paddingBottom: 16, shadowColor: '#000', shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 5, }, tabItem: { flex: 1, alignItems: 'center', justifyContent: 'center', }, middleTabItem: { position: 'absolute', left: '50%', transform: [{ translateX: -35 }], bottom: 20, }, iconContainer: { padding: 8, borderRadius: 8, }, middleIconContainer: { backgroundColor: '#2563eb', borderRadius: 30, padding: 12, shadowColor: '#2563eb', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8, elevation: 6, }, focusedIconContainer: { backgroundColor: '#eff6ff', }, tabLabel: { fontSize: 12, marginTop: 4, color: '#6b7280', }, focusedTabLabel: { color: '#2563eb', fontWeight: '500', }, }); export default CustomTabBar;
3. 配置导航器
在你的导航配置中使用自定义TabBar:
import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import CustomTabBar from './CustomTabBar'; // 导入你的页面组件 import HomeScreen from './screens/HomeScreen'; import SearchScreen from './screens/SearchScreen'; import AddScreen from './screens/AddScreen'; import NotificationsScreen from './screens/NotificationsScreen'; import ProfileScreen from './screens/ProfileScreen'; const Tab = createBottomTabNavigator(); export default function App() { return ( <NavigationContainer> <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />} screenOptions={{ headerShown: false, }} > <Tab.Screen name="Home" component={HomeScreen} options={{ tabBarIcon: { focused: 'home', unfocused: 'home-outline' }, }} /> <Tab.Screen name="Search" component={SearchScreen} options={{ tabBarIcon: { focused: 'search', unfocused: 'search-outline' }, }} /> <Tab.Screen name="Add" component={AddScreen} options={{ tabBarIcon: { focused: 'add', unfocused: 'add-outline' }, tabBarLabel: '', }} /> <Tab.Screen name="Notifications" component={NotificationsScreen} options={{ tabBarIcon: { focused: 'notifications', unfocused: 'notifications-outline' }, }} /> <Tab.Screen name="Profile" component={ProfileScreen} options={{ tabBarIcon: { focused: 'person', unfocused: 'person-outline' }, }} /> </Tab.Navigator> </NavigationContainer> ); }
关键调整点
- 中间Tab索引:根据你的导航项数量调整
isMiddleTab的判断条件 - 凸起高度:修改
middleTabItem的bottom值来调整凸起程度 - 样式匹配:根据设计图调整颜色、图标大小、阴影参数等
- 安全区域适配:如果需要适配不同设备的底部安全区域,可以使用
useSafeAreaInsets钩子动态调整padding
内容的提问来源于stack exchange,提问作者midnighttfoxx
相关产品推荐
相关产品推荐

