从嵌套的 StackNavigator 中隐藏 TabBar 的反应导航屏幕

Posted

技术标签:

【中文标题】从嵌套的 StackNavigator 中隐藏 TabBar 的反应导航屏幕【英文标题】:react-navigation Screen that conceals TabBar from nested StackNavigator 【发布时间】:2018-06-26 08:22:49 【问题描述】:

我是 react-navigation 的新手,我想了解如何执行以下操作:

鉴于此导航结构:

RootTabNavigator 

  LoggedOut_StackNavigator

    ...

  LoggedIn_StackNavigator

    LoggedIn_TabNavigator <-- TabBar rendered by this Navigator

      TabA_StackNavigator

        ScreenA
        ScreenB

我希望能够使用典型的“从右侧滑入”过渡从ScreenA 导航到ScreenB,这样TabBar 在@ 上可见 987654326@,但在ScreenB可见。换句话说,当我导航到ScreenB 时,我希望它占据整个窗口。

一旦用户从ScreenA 转换到ScreenB,他们可以按返回按钮返回到ScreenA,或者使用与TabBar 相同的转换导航到新路线可见。

我的尝试:

navigationOptions.tabBarVisible:此属性似乎仅在应用于TabA_StackNavigator 本身时才有效,这意味着其堆栈中的所有 屏幕也隐藏了TabBar。将其添加到 StackNavigator 内的屏幕没有任何效果。

添加一个新的AllScreens_StackNavigator 作为LoggedIn_TabNavigator 的兄弟并导航到此导航器内的路线,我收到错误:Expect nav state to have routes and index, "routeName":"ScreenB", "params": , "key": "init-id-1516..."。我派出的导航操作尝试执行此操作:


  "action": Object 
    "params": Object ,
    "routeName": "ScreenB",
    "type": "Navigation/NAVIGATE",
  ,
  "params": Object ,
  "routeName": "AllScreens_StackNavigator",
  "type": "Navigation/NAVIGATE",

非常感谢任何帮助!

【问题讨论】:

能否请您为您的导航器发布代码? 要达到你想要的,你应该把你的新路由推送到LoggedIn_StackNavigator的导航器。 【参考方案1】:

编辑:此答案与react-nagivation v1.~(pre v2.0)相关

根据 cmets 的建议,请参阅此问题:

https://github.com/react-navigation/react-navigation-tabs/issues/19


显然,内部组件的navigationOptions 也会影响包含导航器的父导航器。

解决方案

这意味着这段代码应该适合你:

class ScreenB extends React.Component 
  static navigationOptions = 
    header: () => null,  //this will hide the Stack navigator's header (TabA_StackNavigator)
    tabBarVisible: false //this will hide the TabBar navigator's header (LoggedIn_TabNavigator)
  

说明

首先,您可以为每个屏幕(组件)设置导航选项。你可以在上面或这里的代码 sn-p 中看到如何:React Navigation - Screen Navigation Options

第二,你试过了:

将它添加到 StackNavigator 内的屏幕没有任何效果。

它不起作用,因为隐藏 StackNavigator 的标题需要将 header 字段设置为 null

来自React Navigation documentation:

给定 HeaderProps 的 React 元素或函数返回一个 React 元素,显示为标题。 设置为 null 隐藏标题

第三,使用tabBarVisible实际上是正确的,但它只影响TabNavigator。并且要使其仅针对一个选项卡而不是所有选项卡消失,您需要在特定屏幕上进行设置。 ScreenB 在你的情况下。

希望这会有所帮助!

【讨论】:

感谢您的回复。到您发布时,我已经想通了,我还没有机会尝试您的解决方案。我以不同的方式解决了它,并将发布我的解决方案。在又有几个人对对他们有用的方法进行投票后,我将把解决方案标记为正确。再次感谢:) 此解决方案不再适用于 react-navigation v2;请参阅此处以获取有效的解决方案:github.com/react-navigation/react-navigation-tabs/issues/…【参考方案2】:

以下内容最终为我工作,所以我发布它希望它可以帮助其他人。我还没有机会尝试@talzaj 的实现,所以我将把它留给其他人来支持最适合他们的方法。以下解决方案对我来说效果很好,包括在嵌套导航器中。

我更新了我的导航结构:

    LoggedIn_StackNavigator 仍然将 LoggedIn_TabNavigator 作为其屏幕之一,而此 LoggedIn_TabNavigator 是使用 initialRouteName 设置的 LoggedIn_StackNavigator 的初始路由。 LoggedIn_StackNavigator 还包含每个需要全屏显示并隐藏标签栏的屏幕的路由。 (如果您正在重复使用屏幕,其中一些显示标签栏可见,而另一些则不可见,确保为重复使用同一屏幕的路线使用唯一键。李>

导航结构

因此,导航结构如下所示:

RootTabNavigator 

  LoggedOut_StackNavigator

  LoggedIn_StackNavigator

    ScreenA // ( reuse screen component, different route key )

    ScreenB // ( reuse screen component, different route key )

    LoggedIn_TabNavigator <-- TabBar rendered by this Navigator

      TabA_StackNavigator

        ScreenA
        ScreenB

LoggedIn_StackNavigator:

LoggedIn_StackNavigator 看起来像:

import  StackNavigator  from 'react-navigation';
import LoggedIn_TabNavigator from './LoggedIn_TabNavigator';
import  
  ScreenA, 
  ScreenB, 
 from './LoggedIn_TabNavigator/TabA_StackNavigator/Screens';

const LoggedIn_StackNavigator = StackNavigator(
  WithoutTabBar_ScreenA: 
     screen: ScreenA
  ,
  WithoutTabBar_ScreenB: 
    screen: ScreenB
  ,
  LoggedIn_TabNavigator: 
    screen: LoggedIn_TabNavigator
  
, 
  initialRouteName: 'LoggedIn_TabNavigator'
);

export default LoggedIn_StackNavigator;

从那里,我写了一个帮助全屏路由的 HOC:

import React from 'react';
import  withNavigation  from 'react-navigation';
import  fullScreenRoutePrefix  from './somewhere';

export default function withNavigateFullScreen(Child) 

  @withNavigation
  class WithNavigateFullScreenHOC extends React.Component 

    navigateToFullScreenRoute = (routeName, params) =>           
      this.props.navigation.navigate(
        `$fullScreenRoutePrefix$routeName`, params
      );
    

    render() 
      return (
        <Child 
          ...this.props 
          navigateFullScreen=this.navigateToFullScreenRoute 
        />
      );
    
  
  return WithNavigateFullScreenHOC;

然后我可以像这样导航到全屏路线:

import React from 'react';
import  withNavigateFullScreen  from 'components/higher-order';
import  Text  from 'react-native';

@withNavigateFullScreen
export default class ScreenA extends React.Component 
  goToScreenB = () => 
    this.props.navigateFullScreen('ScreenB');
  
  render() 
    return <Text onPress=this.goToScreenB>Go To Screen B</Text>;
  

【讨论】:

以上是关于从嵌套的 StackNavigator 中隐藏 TabBar 的反应导航屏幕的主要内容,如果未能解决你的问题,请参考以下文章

StackNavigator中的StackNavigator中的StackNavigator,TabNavigator切换到错误的选项卡

在react-navigation中从嵌套导航器导航到父屏幕

在反应导航中禁用后退按钮

react-navigation 从嵌套导航器更改活动选项卡

从窗口组件反应导航全屏模式

StackNavigator:无法更改标题标题的字体颜色