当同时使用:Stack Navigator 和 BottomTab Navigator 时,如何在 Stack Navigation Screen 中隐藏底部选项卡?

When using both: Stack Navigator and BottomTab Navigator how do I hide the bottom tab when inside a Stack Navigation Screen?

到目前为止,我有一个带有 2 个选项卡的底部导航(主页和消息)。在 Messages 中时,我可以按下 User 以导航到 ChatScreen,这是来自 Stack Navigator 的屏幕。在 ChatScreen 中,我想 隐藏 BottomTab。我知道可以通过将 tabBarStyle: { display: "none" } 添加到 <Tab.Screen /> 来隐藏它,但这对 ChatScreen 不起作用,因为它不是 Tab.Screen

import * as React from 'react';
import {View, Text} from 'react-native';
import {NavigationContainer, StackActions} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Home from './app/Screens/Home';
import CommentSection from './app/Screens/CommentSection';
import MessageScreen from './app/Screens/MessageScreen';
import ChatScreen from './app/Screens/ChatScreen';
import NavigationHeader from './app/global/headers/NavigationHeader';
import SendOffer from './app/Screens/SendOffer';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/MaterialIcons';
import ChatScreenHeader from './app/Screens/ChatScreen/ChatScreenHeader';

const HomeStack = createNativeStackNavigator();

const HomeStackScreen = () => {
  return (
    <HomeStack.Navigator initialRouteName="Home">
      <HomeStack.Screen
        name="HomeScreen"
        component={Home}
        options={{
          // header: AppBar,
          headerShown: false,
        }}
      />
      <HomeStack.Screen
        name="CommentSection"
        component={CommentSection}
        options={{
          headerTitle: 'Home',
          // animationTypeForReplace: 'push',
          animation: 'slide_from_bottom',
        }}
      />
      <HomeStack.Screen
        name="SendOffer"
        component={SendOffer}
        options={{
          headerTitle: 'Home',
          animation: 'slide_from_right',
        }}
      />
      <HomeStack.Screen
        name="ChatScreen"
        component={ChatScreen} //HIDE BottomTab INSIDE THIS COMPONENT
        options={{
          headerTitle: 'Messages',
          animation: 'slide_from_right',
        }}
      />
    </HomeStack.Navigator>
  );
};

const MessageStack = createNativeStackNavigator();

const MessageStackScreen = () => {
  return (
    <MessageStack.Navigator>
      <MessageStack.Screen
        name="MessageScreen"
        component={MessageScreen}
        options={{
          headerTitle: 'Messages',
          animation: 'slide_from_right',
        }}
      />
      <MessageStack.Screen
        name="ChatScreen"
        component={ChatScreen} //HIDE BottomTab INSIDE THIS COMPONENT
        options={{
          headerTitle: 'Messages',
          headerShown: false,
          animation: 'slide_from_right',
        }}
      />
    </MessageStack.Navigator>
  );
};

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator initialRouteName="Messages">
        <Tab.Screen
        name="Home"
        component={HomeStackScreen}
        options={{
          headerShown: false,
          tabBarLabel: 'Home',
          tabBarIcon: ({ color }) => (
            <Icon name="home" color={color} size={26} />
          ),
        }}
        />
        <Tab.Screen
        name="Messages"
        component={MessageStackScreen}
        options={{
          headerShown: false,
          tabBarLabel: 'Messages',
          tabBarIcon: ({ color }) => (
            <Icon name="chat" color={color} size={26} />
          ),
          // tabBarStyle: { display: "none" }
        }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

您可以使用 createNavigationContainerRef 通过创建 BottomTabNavigator 的组件内的 getCurrentRoute() 函数检查当前路由名称,然后有条件地使用 tabBarStyle建议。

这可能如下所示。

import { createNavigationContainerRef } from "@react-navigation/native"

const ref = createNavigationContainerRef();

const Tab = createBottomTabNavigator();

export default function App() {
  const hide = "ChatScreen" === ref.current?.getCurrentRoute()?.name
   
  return (
    <NavigationContainer>
      <Tab.Navigator initialRouteName="Messages">
        <Tab.Screen
        name="Home"
        component={HomeStackScreen}
        options={{
          headerShown: false,
          tabBarLabel: 'Home',
          tabBarIcon: ({ color }) => (
            <Icon name="home" color={color} size={26} />
          ),
        }}
        />
        <Tab.Screen
        name="Messages"
        component={MessageStackScreen}
        options={{
          headerShown: false,
          tabBarLabel: 'Messages',
          tabBarIcon: ({ color }) => (
            <Icon name="chat" color={color} size={26} />
          ),
          tabBarStyle: { display: hide ? "none" : "flex" }
        }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

二手 by @Escaper from another

useEffect(() => {
    navigation.getParent()?.setOptions({ tabBarStyle: { display: "none" }});
    return () => navigation.getParent()?.setOptions({ tabBarStyle: undefined });
  }, [navigation]);