React Navigation如何从堆栈导航中隐藏tabbar

Ahm*_*adi 4 react-native react-navigation

我有以下堆栈导航和屏幕:

export const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Categories: CategoriesScreen,
    Products: ProductsScreen,
    ProductDetails: ProductDetailsScreen,
})
Run Code Online (Sandbox Code Playgroud)

我想仅在ProductDetailsS​​creen中隐藏选项卡

export const hideTabBarComponents = [
    'ProductDetails',
]

export const MainTabs = createBottomTabNavigator(
    {
        Home: HomeStack,
        Favorite: FavoriteScreen,
        Account: AccountScreen,
        Help: HelpScreen,
        Events: EventsScreen
    },
    {
        navigationOptions: ({ navigation }) => ({

            tabBarIcon: ({ focused, tintColor }) => {
                ...
            },
            tabBarLabel: ({ focused, tintColor }) => {
                ...
            },

            tabBarVisible: ! hideTabBarComponents.includes(navigation.state.routeName)

        }),
    }
);
Run Code Online (Sandbox Code Playgroud)

无法将任何选项传递到"堆栈导航"选项卡导航的问题

并非所有堆叠屏幕都只有其中一个

Ahm*_*adi 31

经过一番搜索后,下面的代码解决了这个问题:

HomeStack.navigationOptions = ({ navigation }) => {

    let tabBarVisible = true;

    let routeName = navigation.state.routes[navigation.state.index].routeName

    if ( routeName == 'ProductDetails' ) {
        tabBarVisible = false
    }

    return {
        tabBarVisible,
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用导航 6 :则 tabBarVisible 选项不再存在。您可以通过在选项中指定 tabBarStyle: { display: 'none' } 来实现相同的行为。 (9认同)
  • @chenop 在 v6 中,没有 `tabBarVisible`,XD (4认同)
  • 如果您来这里寻找 React Navigation v5 解决方案,您可以在[此处](/sf/answers/4260771721/)找到它 (2认同)

Jor*_*els 24

对于 React Navigation 5,您可以在堆栈组件内执行此操作:

props.navigation.dangerouslyGetParent().setOptions({
  tabBarVisible: false
});
Run Code Online (Sandbox Code Playgroud)

https://reactnavigation.org/docs/en/navigation-prop.html#setoptions---update-screen-options-from-the-component

使用它时要小心,一旦卸载组件,您需要将 tabBarVisible 重置为 true。

例如,在 Stack 组件中使用 React 钩子:

    useEffect(() => {
      const parent = props.navigation.dangerouslyGetParent();
      parent.setOptions({
        tabBarVisible: false
      });
      return () =>
        parent.setOptions({
          tabBarVisible: true
        });
    }, []);
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用后退按钮重置 Stack.Screen 组件中的 tabBarVisible,如下所示:

    const StackNav = (props) => (
      <Stack.Screen
        name='name'
        component={Name}
        options={{
          headerTitle: 'Name',
          headerLeft: () => (
            <Text
              onPress={() =>
                props.navigation.setOptions({
                tabBarVisible: true
                })
              }
            >
              on back
            </Text>
          )
        }}
      />
    }
Run Code Online (Sandbox Code Playgroud)

(第二种方法效果更好。)


Cha*_*chi 21

这就是我在堆栈中的特定屏幕中隐藏标签栏的方式(React Nav 5.x & 6.x)

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
const ProfileStack = createStackNavigator();
    
const ProfileNavigator = ({ navigation, route }) => {
        React.useLayoutEffect(() => {
            const routeName = getFocusedRouteNameFromRoute(route);
            if (routeName === "Group"){
                navigation.setOptions({tabBarVisible: false});
            }else {
                navigation.setOptions({tabBarVisible: true});
            }
        }, [navigation, route]);
        return(
            <ProfileStack.Navigator>
                <ProfileStack.Screen name="Profile" component={ProfileScreen} />
                <ProfileStack.Screen name="Group" component={GroupScreen} />
            </ProfileStack.Navigator>
        )};
Run Code Online (Sandbox Code Playgroud)

如果你们有很多屏幕需要隐藏标签栏,请使用这些路线名称的字符串数组,如果焦点路线名称包含在该数组中,则隐藏标签栏

const tabHiddenRoutes = ["Group","Map"];

if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
  navigation.setOptions({tabBarVisible: false});
 }else{
 navigation.setOptions({tabBarVisible: true});
}
Run Code Online (Sandbox Code Playgroud)

[编辑] - 在v6 的情况下,使用display因为tabBarVisible不赞成使用tabBarStyle-

if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
  navigation.setOptions({tabBarStyle: {display: 'none'}});
 } else {
 navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
Run Code Online (Sandbox Code Playgroud)

  • 有时对我来说,行为不一致,选项卡消失但留下显示(与隐藏栏的大小完全相同,其中没有内容,只是灰色背景 (13认同)
  • 我也使用了这个解决方案,但是如果您来自 v6,请使用 `navigation.setOptions({tabBarVisible: false});`,而不是 `navigation.setOptions({tabBarStyle: {display: 'none'}}) ;` (4认同)
  • 这是其他解决方案中最好的解决方案。显示和隐藏 BottomTabBar 的巧妙而有效的方法。多谢 (2认同)
  • @Hilory 你成功解决你的问题了吗?我有一个类似的,当我进入下一个屏幕时,它似乎保留了导航的边界框。仅视觉上。 (2认同)

小智 13

如果您正在使用navigation 6Than The tabBarVisible option is no longer present。您可以通过在选项中指定来实现相同的行为tabBarStyle: { display: 'none' }


小智 8

首先让我们创建一个堆栈导航器并将其命名为 StackHome

const StackHome = createStackNavigator(
{
 Home: Home,
 CustomHide: CustomHide,
});
// This code let you hide the bottom app bar when "CustomHide" is rendering
StackHome.navigationOptions = ({ navigation }) => {
 let tabBarVisible;
  if (navigation.state.routes.length > 1) {
navigation.state.routes.map(route => {
  if (route.routeName === "CustomHide") {
    tabBarVisible = false;
  } else {
    tabBarVisible = true;
  }
});
 }

 return {
   tabBarVisible
 };
};
export default StackHome;
Run Code Online (Sandbox Code Playgroud)


小智 6

如果像我一样,您在 React Navigation 6 中努力完成这项工作,那么我是如何实现它的...我有一个包含多个堆栈的 BottomTabNavigator,并且想要隐藏主堆栈的特定屏幕(播放器)上的选项卡栏

    import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
    ...
    
    <BottomTabNavigator.Screen 
         name="HomeStack" 
         component={HomeStack} 
         options={({route}) =>({ tabBarStyle: getTabBarStyle(route) })} />
    
    ....
    const getTabBarStyle = (route) => {  
      const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
      let display = (routeName === 'Player') ? 'none':'flex';
      return {display}
    }
Run Code Online (Sandbox Code Playgroud)