React Navigation V5 在特定屏幕中隐藏底部选项卡

React Navigation V5 Hide Bottom Tab in Specific Screens

我正在使用 React Navigation 版本 5 创建一个 React Native 应用程序,我有一个底部选项卡导航器,在选项卡导航器的每个屏幕内嵌套了一个堆栈导航器。我只希望底部标签栏显示在每个堆栈导航器的第一页上。这是显示我的应用程序基本导航功能的小吃:https://snack.expo.io/@brforest/hide-tab-1. Per the bottom tab documentation,有一个 tabBarVisible 选项属性,但是:

Hiding tab bar can cause glitches and jumpy behavior. We recommend the tab navigator inside of a stack navigator instead.

将选项卡导航器嵌套在堆栈导航器中的指南是 here. I tried using this method, but I could only get it to work if I had only one stack navigator, but I need to have a stack navigator for each of the tab screens. Here is my (unsuccessful) attempt to use this method on the same app from the previous snack: https://snack.expo.io/@brforest/hide-tab-2。在此,我在单个堆栈导航器中嵌套了多个选项卡导航器,以尝试推断文档中建议的方法。正如您在这个 snack 中看到的,堆栈内的导航不再起作用,但选项卡仍然有效。

对我来说,将堆栈导航器嵌套在选项卡导航器中(就像我在第一个小吃中所做的那样)比尝试将同一个选项卡导航器嵌套在大型堆栈导航器中更有意义。但是,我想按照文档找到一种不会导致 "glitchy and jumpy behavior." 关于如何实现所需导航功能的建议?

谢谢!

就像您提到的那样,如果您只希望每个堆栈中的第一个屏幕显示底部标签栏,那么我建议您使用第二种方法。创建一个基本堆栈导航器,第一个屏幕是选项卡导航器本身:

const TabScreens = ({navigation}) => { // Tab navigator with only the screens that require bottom tab bar
  return (
    <Tab.Navigator
      initialRouteName="Home"
      tabBarOptions={{
        activeTintColor: '#e91e63',
      }}>
      <Tab.Screen
        name="Home"
        component={Home}
        options={{
          tabBarLabel: 'Home',
        }}
      />
      <Tab.Screen
        name="Welcome"
        component={Welcome}
        options={{
          tabBarLabel: 'Welcome',
        }}
      />
    </Tab.Navigator>
  );
};

创建选项卡导航器后,在主渲染器中使用:

    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Stack"
          component={TabScreens}
        />
        <Stack.Screen             // Add any number of extra screens that do not require the bottom tab here
         name="Other screen 1"
         component={OtherScreen1} />
        <Stack.Screen             
         name="Other screen 2"
         component={OtherScreen2} />
      </Stack.Navigator>
    </NavigationContainer>

这样您就不必 fiddle 使用底部选项卡组件。您还可以在属于基本堆栈导航器的任何屏幕和属于选项卡导航器的任何屏幕之间导航。此处唯一需要注意的是,每次您导航到此处和返回时,除了选项卡导航器中的屏幕之外的所有屏幕都将被安装和卸载。

通过互联网我找到了自己的方法来隐藏特定堆栈屏幕中的底部选项卡。

export default function SignStack({ navigation, route }) {

   useEffect(() => {
    if (route.state?.index) {
      navigation.setOptions({
        tabBarVisible: false,
      });
    } else {
      navigation.setOptions({
        tabBarVisible: true,
      });
    }
  }, [navigation, route.state?.index]);



return <Stack.Navigator> ... </Stack.Navigator>

}

这将仅在第一个堆栈屏幕上显示底部选项卡。

2020 年 11 月 17 日更新

使用 getFocusedRouteNameFromRoute 隐藏底部选项卡,此示例仅在 AuthSettings 屏幕上显示底部选项卡。

  const routeName = getFocusedRouteNameFromRoute(route) ?? 'Auth';

  useEffect(() => {
    navigation.setOptions({
      tabBarVisible: ['Auth', 'Settings'].includes(routeName),
    });
  }, [navigation, routeName]);

为什么不先解决 TLDR

上述解决方案基于渲染隐藏屏幕底部选项卡route.state.index如果您有平行导航路线,则可以使用上述解决方案。

假设您有两个选项卡导航用户堆栈和主页堆栈,并且在用户堆栈上您有两个屏幕配置文件和设置,如果您想隐藏设置屏幕上的底部栏,您将使用上述有效的解决方案很好但是当您直接从主页导航到用户设置屏幕时,底部选项卡栏显示在设置屏幕上并隐藏在配置文件屏幕上,这是因为设置屏幕的 route.state.index0 而配置文件屏幕是1.

简单的方法

  options={{
        tabBarVisible: false,
      }}