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

如何用@react-navigation/bottom-tabs实现底部标签栏下方圆形效果

实现@react-navigation/bottom-tabs底部标签栏下方圆形效果的调整方案

要实现目标中的底部标签栏下方圆形凸起效果,核心思路是自定义tabBar组件,通过绝对定位的圆形元素结合选中状态的位置偏移来实现,具体步骤如下:

1. 编写自定义TabBar组件

通过View构建tabBar容器,管理选中状态,并在选中标签对应位置添加绝对定位的圆形元素,确保tab内容层级高于圆形元素:

import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { useNavigationState } from '@react-navigation/native';

const CustomTabBar = ({ state, descriptors, navigation }) => {
  const activeIndex = state.index;

  return (
    <View style={styles.tabBarContainer}>
      {/* 底部圆形指示器,随选中标签偏移 */}
      <View 
        style={[
          styles.circleIndicator,
          { left: `${activeIndex * 25}%` } // 4个标签时每个占25%宽度,按需调整
        ]}
      />
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label = options.tabBarLabel ?? options.title ?? route.name;
        const isFocused = state.index === index;

        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 } : {}}
            onPress={onPress}
            onLongPress={onLongPress}
            style={styles.tabItem}
          >
            <Text style={{ color: isFocused ? '#1677ff' : '#888' }}>{label}</Text>
            {/* 如需图标,在此处添加Icon组件并根据isFocused切换样式 */}
          </TouchableOpacity>
        );
      })}
    </View>
  );
};

const styles = StyleSheet.create({
  tabBarContainer: {
    flexDirection: 'row',
    height: 60,
    backgroundColor: '#fff',
    justifyContent: 'space-around',
    alignItems: 'center',
    position: 'relative',
    borderTopWidth: 1,
    borderTopColor: '#eee',
    overflow: 'visible', // 允许圆形元素超出容器范围
  },
  tabItem: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1, // 确保tab内容在圆形指示器上方
  },
  circleIndicator: {
    position: 'absolute',
    bottom: -10, // 控制圆形突出tabBar的高度
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: '#fff',
    borderWidth: 1,
    borderColor: '#eee',
    transform: [{ translateX: -20 }], // 让圆形居中到对应tab的位置
    // 添加阴影增强立体感(iOS/Android兼容)
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 3,
    elevation: 2,
  },
});

2. 配置Bottom Tabs使用自定义TabBar

在createBottomTabNavigator的配置中,指定tabBar为自定义组件:

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator
      tabBar={(props) => <CustomTabBar {...props} />}
      // 可添加其他全局配置,如screenOptions
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
      <Tab.Screen name="Messages" component={MessagesScreen} />
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

按需调整细节

  • 若标签数量不是4个,修改circleIndicator的left值计算逻辑,比如3个标签时改为${activeIndex * 33.33}%
  • 调整circleIndicator的bottom、width、height参数,可改变圆形的大小和突出程度
  • 若需要选中时圆形颜色变化,可根据activeIndex动态绑定backgroundColor属性
  • 图标样式可根据isFocused状态切换颜色或图标资源

内容的提问来源于stack exchange,提问作者Hồng Thảo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:17:43