You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native中创建带圆角和内嵌背景的Bottom Tab Navigator?

自定义凸起式Tab Bar 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:10:35