如何使用TabNavigation显示反应导航中的标题

时间:2017-02-21 00:50:10

标签: react-native react-navigation

我注意到StackNavigation中的视图显示了标题标题但是如果我在TabNavigation中设置了相同的屏幕,则它不会显示标题。如果我在每个选项卡周围包装StackNavigation,或者将TabNavigation包装在StackNavigation中,它只显示一个标题。

为什么TabNavigation中的屏幕不显示标题 - 这是预期的行为吗?如果是这样,最好在每个标签中使用StackNavigation,或者在TabNavigation周围使用一个大的StackNavigation吗?

//标签导航不会在每个屏幕中显示标题标题

const TabsNavigator = TabNavigator({
  Home: {
    screen:HomeScreen,
  },
  Profile: {
    screen: ProfileScreen,
  },
}, {
  tabBarOptions: {
    activeTintColor: '#e91e63',
  },
  navigationOptions: {
    header: {
      visible: true,
    },
  },
});

标题显示我将其包装在StackNavigator中

default StackNavigator({
  Home: { screen: TabsNavigator },
});

或者以这种方式做得更好

 export TabsNavigator = TabNavigator({
      Home: {
        screen:StackNavigator({
          Home: { screen: HomeScreen },
        }),
      },
      Profile: {
        screen: StackNavigator({Profile: {screen: ProfileScreen}}),
      },
    }, {
      tabBarOptions: {
        activeTintColor: '#e91e63',
      },
      navigationOptions: {
        header: {
          visible: true,
        },
      },
    });

4 个答案:

答案 0 :(得分:9)

即使这是一个相当古老的问题,我几天前就已经有了这个问题,所以我要加上我的两分钱,希望这对未来的其他人也有用。

React Navigation是一款令人惊叹的产品,具有大量的自定义功能,但有时也会引起混淆,这也适用于文档的某些部分。从当前版本状态开始,navigationOptions对于所有屏幕都是通用的,但可用导航选项的列表取决于添加屏幕的导航器。" https://reactnavigation.org/docs/tab-navigator.html#navigationoptions-used-by-tabnavigator因此header选项不起作用,因为TabNavigator本身不可用。

关于哪种方法最好的问题取决于您希望通过应用程序本身的导航完成什么。如果您将TabNavigator放在StackNavigator内,那么标题组件对于TabNavigator内的所有标签都是通用的,这意味着标签转换将生效,但标题会赢得&#t从最高位置移动。另一方面,如果您选择在每个选项卡中嵌套StackNavigator,则标题将在每个选项卡内呈现,这意味着标题将沿着选项卡过渡动画移动。

我快速demo让你看到差异,code也可用,如果你想玩它。

答案 1 :(得分:0)

根据React-Navigation TabNavigator Docs,没有标题navigationOption。因此,当您编写以下代码时,实际上是在设置一个不存在的值,因此您所做的事情不会影响任何内容。

2017-05-24 00:00:00

可悲的是,在这种情况下你需要一个StackNavigator。

答案 2 :(得分:0)

我使用的一般结构是这样的,创建一个选项卡导航器,然后为每个选项卡呈现堆栈。在此示例中,我不希望 LiveMap 上有标题,但我希望在其他两个选项卡上有标题。任何有意义的命名取决于你。然后在每个堆栈中渲染有意义的屏幕。

const Tab = createBottomTabNavigator();
const TrainStack = createStackNavigator();
const MapStack = createStackNavigator();
const BusStack = createStackNavigator();

然后每个堆栈为该子集呈现我想要的任何屏幕

const MapNavigator = () => {
  return (
    <MapStack.Navigator
      initialRouteName="LiveMap"
      screenOptions={{headerShown: false}}>
      <MapStack.Screen name="Live Map" component={LiveMap} />
      <MapStack.Screen name="Show Routes" component={AllRoutes} />
      <MapStack.Screen name="Select Routes" component={SelectRoutes} />
    </MapStack.Navigator>
  );
};

标签导航器将为每个标签呈现我的堆栈。

const MainNavigator = () => (
  <Tab.Navigator
    tabBarOptions={{
      activeTintColor: 'orange',
      keyboardHidesTabBar: true,
    }}
    initialRouteName="Live Map">
    <Tab.Screen
      name="Buses"
      component={BusNavigator}
      options={{
        tabBarLabel: 'Buses',
        tabBarIcon: ({color, size}) => (
          <BusIcon height={30} width={30} color={color} />
        ),
      }}
    />
    <Tab.Screen
      name="Live Map"
      component={MapNavigator}
      options={{
        tabBarLabel: 'Map',
        tabBarIcon: ({color}) => (
          <View
            height={100}
            width={100}
            style={{
              display: 'flex',
              alignItems: 'center',
              backgroundColor: '#fff',
              paddingTop: 8,
              borderRadius: 70,
            }}>
            <MapIcon height={50} width={50} color="orange" />
          </View>
        ),
      }}
    />
    <Tab.Screen
      name="Trains"
      component={TrainNavigator}
      options={{
        tabBarLabel: 'Trains',
        tabBarIcon: ({color, size}) => (
          <TrainIcon height={30} width={30} color={color} />
        ),
      }}
    />
  </Tab.Navigator>

答案 3 :(得分:0)

我知道这个问题已经有了答案,但我只想展示我如何使用 React Navigation > 5.x.x 为自己解决这个问题。

Juan 的回答描述了设置它的最佳方式,同时还展示了它是如何完成的,以便人们可以理解导航的外观,这对我们视觉学习者也有一些帮助。这对我当时来说有点难以理解,但希望以后能帮助到其他人。

我发现最好的方法是分解应用程序路由的层次结构。对我来说,我的看起来像这样。

               LoginNavigation                      HomeNavigation   
                     |                                    |
      LoginScreen        RegisterScreen        HomeStack      ProfileStack
                                                   |               |
                                              HomesScreen     ProfileScreen

我的 LoginNavigation 堆栈包含两个屏幕:登录屏幕和注册屏幕。在我的应用中,我不需要在此处设置标签导航,因此将这些屏幕包装在 StackNavigator 中是合适的。另一方面,我有我的 HomeNavigation 堆栈,其中包含一个主屏幕和一个配置文件屏幕。唯一的问题是我的屏幕被包裹在不产生标题的 TabNavigator 中。

为了解决这个问题,我们实际上需要用 StackNavigators 包裹我们的两个屏幕(HomeScreen 和 ProfileScreen),然后用 TabNavigator 包裹所有内容。意识到这一点后,这样做实际上更有意义。为什么?好吧,假设在我的主屏幕上,我有一些帖子,我希望用户能够看到帖子以及随之而来的所有评论。好吧,我不会为此设置另一个选项卡,因为那太愚蠢了。相反,我们会将其添加到我们的 HomeStack 导航中。

                       HomeNavigation   
                             |
            HomeStack                 ProfileStack
                 |                         |
     HomesScreen    PostScreen       ProfileScreen

当查看类似 ProfileStack 之类的东西时,这种结构现在似乎很明显,其中该堆栈可能有多个分支,例如设置、关注者、图片...... 希望显示结构有助于人们理解这一点,也有助于我。

下面是我的 AppStackNavigator 文件,用于查看代码结构。

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import Login from '../screens/Login';
import Register from '../screens/Register';
import FirstProfileImage from '../screens/FirstProfileImage';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Home from '../screens/Home';
import Profile from './../screens/Profile';

const LoginStack = createStackNavigator();
const HomeTabs = createBottomTabNavigator();
const HomeStack = createStackNavigator();
const ProfileStack = createStackNavigator();
const AppStack = createStackNavigator();

const LoginStackNavigator = () => (
  <LoginStack.Navigator screenOptions={{headerStyle: {elevation: 0},cardStyle: {backgroundColor: '#ffffff'}}}>
    <LoginStack.Screen name="Login" component={Login}/>
    <LoginStack.Screen name="Sign Up" component={Register}/>
    <LoginStack.Screen name="Profile Image" component={FirstProfileImage}/>
  </LoginStack.Navigator>
)

const HomeStackNavigator = () => (
  <HomeStack.Navigator>
    <HomeStack.Screen name="Home" component={Home} />
  </HomeStack.Navigator>
)

const ProfileStackNavigator = () => (
  <ProfileStack.Navigator>
    <ProfileStack.Screen name="Profile" component={Profile} />
  </ProfileStack.Navigator>
)

const HomeTabNavigator = () => (
    <HomeTabs.Navigator>
      <HomeTabs.Screen name="HomeStack" component={HomeStackNavigator} />
      <HomeTabs.Screen name="ProfileStack" component={ProfileStackNavigator} />
    </HomeTabs.Navigator> 
)

const AppStackNavigator = () => (
    <AppStack.Navigator initialRouteName={'HomeScreen'} screenOptions={{headerStyle: {elevation: 0},cardStyle: {backgroundColor: '#ffffff'}}} headerMode='none'>
      <AppStack.Screen name="LoginScreen" component={LoginStackNavigator}/>
      <AppStack.Screen name="HomeScreen" component={HomeTabNavigator}/>
    </AppStack.Navigator>  
)

export default AppStackNavigator;

我确实同意这有点矫枉过正,我们可以消除必须跟踪每个单独导航器的问题,但在他们为此添加功能之前,这是目前有效的方法。希望这个解释有点帮助。感谢您参加我的 TED 演讲。