如何在React Navigation 6中隐藏特定屏幕中的tabBar?

wa7juj8i  于 2022-11-17  发布在  React
关注(0)|答案(5)|浏览(210)

如何在react-navigation 6中隐藏特定屏幕中的标签栏...而不更改导航结构,因为它是the only option available in the docs here

vcudknz3

vcudknz31#

有时候我会用这种方法

import { getFocusedRouteNameFromRoute } from ‘@react-navigation/native’;

 export const MainNavigator = () => {
  const getTabBarVisibility = (route) => {
    const routeName = getFocusedRouteNameFromRoute(route);
    const hideOnScreens = [SCREENS.REVIEW_ORDER, SCREENS.ORDER_PAYMENT]; // put here name of screen where you want to hide tabBar
    return hideOnScreens.indexOf(routeName) <= -1;
  };
  return (
    <Tab.Navigator>
      <Tab.Screen
        name={SCREENS.ORDER}
        component={OrderNavigator}
        options={({ route }) => ({
          tabBarVisible: getTabBarVisibility(route),
        })}
      />
      <Tab.Screen name={SCREENS.REWARDS} component={SweetRewardsNavigator} />
      <Tab.Screen name={SCREENS.MY_ACCOUNT} component={MyAccountNavigator} />
    </Tab.Navigator>
  );
};
cpjpxq1n

cpjpxq1n2#

我就是这么做的。
我正在寻找一种方法来隐藏tabBar在我的所有屏幕上的ProductsRoutes,除了主屏幕.(初始路线在ProductsRoutes导航器)

以下是产品导航器:

const ProductsRoutes = (): JSX.Element => {
  return (
    <Navigator
      initialRouteName="Home"
      screenOptions={{
        headerShown: false,
      }}
    >
      <Screen name="Home" component={Home} />
      <Screen name="Details" component={Details} />
      <Screen name="Cart" component={Cart} />
      <Screen name="Catalog" component={Catalog} />
      <Screen name="Sales" component={Sales} />
      <Screen name="Favorites" component={Favorites} />
    </Navigator>
  );
};

在我的选项卡上我正在使用的路由

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';

了解ProductsNavigator上的哪个屏幕是主屏幕,哪个不是。基于该条件,我可以将display:'none'或'display:' flex '设置为Screen props上的tabBarStyle props:

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';

const TabRoutes = (): JSX.Element => {
  return (
    <Navigator
      screenOptions={{
        headerShown: false,
      }}
    >
      <Screen
        name="Store"
        component={ProductsRoutes}
        options={({ route }) => {
          const focusedRouteName = getFocusedRouteNameFromRoute(route);
          if (focusedRouteName === 'Home') {
            return {
              tabBarStyle: { display: 'flex' },
            };
          }

          return {
            tabBarStyle: { display: 'none' },
          };
        }}
      />
    </Navigator>
  );
};

希望这对你有所帮助

zlhcx6iw

zlhcx6iw3#

var scroll = 0; // at top

const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
    let contentOffsetY = e.nativeEvent.contentOffset.y;
    let diff = contentOffsetY - scroll;
    if (diff < 0) {
      navigation.setOptions({tabBarStyle: {display: 'flex'}});
    } else {
      navigation.setOptions({tabBarStyle: {display: 'none'}});
    }
    scroll = contentOffsetY;
  };

将此传递给任何scrollview组件的onScroll

vof42yt1

vof42yt14#

关键字是调用setOptions并将tabBarStyle设置为{display:'none'}
首先,我们在父导航器上设置id,如

<Tab.Navigator
      id="tabs"
      tabBar={props => <FooterTabs {...props} style={{display: 'flex'}} />} //<-- add a style with display:flex means tabbar is visible by default
      >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Search" component={SearchScreen} />
      <Tab.Screen name="Chat" component={ChatScreen} />
    </Tab.Navigator>

假设我们想隐藏聊天屏幕中的标签栏
在聊天屏幕中,输入这样代码

const ChatScreen = ({navigation}) => {
  useEffect(() => {
    navigation.getParent('tabs').setOptions({tabBarStyle: {display: 'none'}});
    return ()=>{
    //when leave this screen, and the hooks disposed, we set tabBarStyle to {}, means we will use the default style defined above, that is display:'flex'
 
      navigation.getParent('tabs').setOptions({tabBarStyle: {}});
    };
  }, [navigation]);
...

您可能注意到,根标签导航器中的标签栏是一个自定义组件,因此在FooterTabs中,关键代码如下所示

const FooterTabs = props => {
  const {state, navigation, descriptors, insets, style} = props;
  const focusedRoute = state.routes[state.index];
  const focusedDescriptor = descriptors[focusedRoute.key];
  const focusedOptions = focusedDescriptor.options;

  const {
    tabBarShowLabel,
    tabBarHideOnKeyboard = false,
    tabBarVisibilityAnimationConfig,
    tabBarStyle, //<-- this is get from options,which we set from sub screens 
    tabBarBackground,
    tabBarActiveTintColor,
    tabBarInactiveTintColor,
    tabBarActiveBackgroundColor,
    tabBarInactiveBackgroundColor,
  } = focusedOptions;

  return (
    <HStack
      style={{...props.style, ...tabBarStyle}} //<-- we set the style over here, so when in some specific screen set tabbarstyle to override the display property to 'none', can final make tabbar hidden
      ...

上面代码是从official bottom tabbar component中获取的

5f0d552i

5f0d552i5#

在我的例子中,我有一个堆栈导航器屏幕,在其中隐藏父导航器和祖导航器的tabBar和头。

export const MyNav = ({
  route,
  navigation
}) => {

   React.useLayoutEffect(() => {
    
        const routeName = getFocusedRouteNameFromRoute(route);

        if (routeName === 'RouteThatNeedsHiddenTabBarsAndHiddenHeader') {
          navigation.setOptions({ tabBarStyle: { display: 'none' } });
          navigation.getParent()?.setOptions({ headerShown: false });
          navigation.getParent()?.getParent()?.setOptions({ tabBarStyle: { display: 'none' } });
        } else {
          navigation.setOptions({
            tabBarStyle: { ...defaultTabBarStyle, display: 'flex' }
          });
          navigation.getParent()?.setOptions({ headerShown: true });
          navigation.getParent()?.getParent()?.setOptions({ tabBarStyle: {display: 'flex' });
        }
      }, [navigation, route]);

      return (
        <Stack.Navigator>
          <Stack.Screen
            name="NormalRoute"
            component={NormalScreen}
          />
          
          <Stack.Screen
            name="RouteThatNeedsHiddenTabBarAndHiddenHeader"
            component={SpecialScreen}              />
        </Stack.Navigator>
      );
  }

如果只需要调整1个屏幕,则更简单的方法是在目标屏幕中运行代码,如下所述:
https://stackoverflow.com/a/70153935/1979861

相关问题