35

我注意到 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

4 回答 4

16

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

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

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

我做了一个快速演示让你看看有什么不同,如果你想玩它,也可以使用代码。

于 2017-11-10T06:41:01.277 回答
1

我知道这个问题已经有了答案,但我只想展示我能够使用React Navigation > 5.x.x.

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

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

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

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

为了解决这个问题,我们实际上需要将两个屏幕(HomeScreen 和 ProfileScreen)StackNavigators包裹起来,然后用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 演讲。

于 2021-05-30T15:04:17.820 回答
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>
于 2021-05-26T12:40:06.073 回答
0

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

navigationOptions: {
  header: { visible: true },
}

遗憾的是,在这种情况下您需要 StackNavigator。

于 2017-06-02T13:41:07.757 回答