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

求助:基于@react-navigation/bottom-tabs实现可横向滑动底部标签页

实现可横向滑动分页的底部标签页

要解决你遇到的问题,我们需要自定义@react-navigation/bottom-tabs的底部导航栏,结合横向滚动容器(比如ScrollView)把10个标签分成两组,每组5个,实现滑动切换标签组的效果。以下是具体实现步骤和代码:

1. 准备工作

确保你已经安装了必要依赖:

npm install @react-navigation/native @react-navigation/bottom-tabs react-native-screens react-native-safe-area-context

2. 完整代码实现

import React from 'react';
import { View, Text, ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

// 替换成你自己的页面组件
const Page1 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab1</Text></View>;
const Page2 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab2</Text></View>;
const Page3 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab3</Text></View>;
const Page4 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab4</Text></View>;
const Page5 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab5</Text></View>;
const Page6 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab6</Text></View>;
const Page7 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab7</Text></View>;
const Page8 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab8</Text></View>;
const Page9 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab9</Text></View>;
const Page10 = () => <View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>Tab10</Text></View>;

// 将标签分成两组,每组5个
const tabGroups = [
  [
    { name: 'Tab1', component: Page1 },
    { name: 'Tab2', component: Page2 },
    { name: 'Tab3', component: Page3 },
    { name: 'Tab4', component: Page4 },
    { name: 'Tab5', component: Page5 },
  ],
  [
    { name: 'Tab6', component: Page6 },
    { name: 'Tab7', component: Page7 },
    { name: 'Tab8', component: Page8 },
    { name: 'Tab9', component: Page9 },
    { name: 'Tab10', component: Page10 },
  ],
];

const Tab = createBottomTabNavigator();

// 自定义可滑动的底部标签栏
const CustomTabBar = ({ state, descriptors, navigation }) => {
  return (
    <ScrollView
      horizontal
      showsHorizontalScrollIndicator={false}
      style={styles.tabBarContainer}
    >
      {/* 第一组标签 */}
      <View style={styles.tabGroup}>
        {tabGroups[0].map((route, index) => {
          const isFocused = state.index === index;
          const onPress = () => {
            if (!isFocused) {
              navigation.navigate(route.name);
            }
          };

          return (
            <TouchableOpacity
              key={route.name}
              onPress={onPress}
              style={[styles.tabItem, isFocused && styles.activeTab]}
            >
              <Text style={[styles.tabText, isFocused && styles.activeTabText]}>
                {route.name}
              </Text>
            </TouchableOpacity>
          );
        })}
      </View>

      {/* 第二组标签 */}
      <View style={styles.tabGroup}>
        {tabGroups[1].map((route, index) => {
          const realIndex = index + 5; // 第二组对应导航器的第5-9个索引
          const isFocused = state.index === realIndex;
          const onPress = () => {
            if (!isFocused) {
              navigation.navigate(route.name);
            }
          };

          return (
            <TouchableOpacity
              key={route.name}
              onPress={onPress}
              style={[styles.tabItem, isFocused && styles.activeTab]}
            >
              <Text style={[styles.tabText, isFocused && styles.activeTabText]}>
                {route.name}
              </Text>
            </TouchableOpacity>
          );
        })}
      </View>
    </ScrollView>
  );
};

// 样式定义
const styles = StyleSheet.create({
  tabBarContainer: {
    backgroundColor: '#ffffff',
    borderTopWidth: 1,
    borderTopColor: '#e0e0e0',
  },
  tabGroup: {
    flexDirection: 'row',
    paddingHorizontal: 12,
  },
  tabItem: {
    paddingVertical: 14,
    paddingHorizontal: 18,
    alignItems: 'center',
  },
  activeTab: {
    borderBottomWidth: 2,
    borderBottomColor: '#1976d2',
  },
  tabText: {
    fontSize: 14,
    color: '#666666',
  },
  activeTabText: {
    color: '#1976d2',
    fontWeight: '500',
  },
});

// 主组件
export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator
        tabBar={(props) => <CustomTabBar {...props} />}
        screenOptions={{ headerShown: false }}
      >
        {/* 注册所有标签页面 */}
        {tabGroups.flat().map((route) => (
          <Tab.Screen
            key={route.name}
            name={route.name}
            component={route.component}
          />
        ))}
      </Tab.Navigator>
    </NavigationContainer>
  );
}

关键说明

  • 用ScrollView实现横向滚动的标签容器,把两组标签分别放在独立View中,确保每组5个标签不会拥挤
  • 自定义TabBar通过state.index判断当前选中标签,同步更新激活样式
  • 点击标签时通过navigation.navigate切换对应页面,保持原生底部导航的逻辑一致性
  • 如果需要实现页面滑动自动切换标签,可以在页面组件中用PanResponder或react-native-gesture-handler监听滑动手势,再调用navigation.navigate切换标签

内容的提问来源于stack exchange,提问作者Govind Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:40:27