正确嵌套底部标签与堆栈中的外部屏幕

时间:2021-05-18 20:07:22

标签: react-native react-navigation react-navigation-v5 react-navigation-bottom-tab

我正在使用 react-native 0.64 和 react-navigation v5 构建应用。

我正在尝试实现一个顶部有抽屉的导航结构,一个主屏幕(没有底部标签),带有导航到 5 个屏幕的按钮 - 那些有底部标签的 - 和一个有 6 个标签的底部标签:相同的 5 个屏幕(每个它们允许导航到不同的子屏幕)和主屏幕的标签

根据 react-navigation 文档 (Hiding tab bar in specific screens),在我的实现中,我避免使用“tabBarVisible”道具,而是将 HomeScreen 放在父 Stack 中,而BottomTab 是其屏幕之一。问题是我希望在BottomTab中有一个HomeScreen的选项卡,即使这个屏幕不在BottomTab内(当用户按下Home选项卡时,应用程序应该导航到BottomTab不再存在的HomeScreen) .

我试图实现的是这样的结构:

  • [抽屉]
    • [主堆栈]
      • 主屏幕
      • [底部标签]
        • HomeScreen(带有“tabPress”=> 导航回主屏幕的侦听器道具)
        • [堆栈 1]
          • 屏幕 1
          • DetailScreen1
        • [堆栈 2]
          • 屏幕 2
          • DetailScreen2
        • 。 . . (其他 3 叠)

问题:

  1. 嵌套/配置导航器以获得预期的最终结果的正确方法是什么?将 HomeScreen 作为父 Stack 和子 BottomTab 上的屏幕组件是否“安全”和正确?

  2. 这似乎是一个沉重的解决方案(抽屉内的堆栈内的底部选项卡内的 5 个堆栈,很快我将为授权屏幕添加另一个堆栈),这会减慢应用程序的运行速度:有没有更有效的方法使用预先构建的导航器或其他构建 ie 来组织导航器。用于 tabBar 的自定义组件,以便可能所有屏幕都在较少的堆栈中(一个?)或其他任何可以帮助我构建更轻量级解决方案的组件?

我在 expo.io 上发布了完整(且简单)的 sample code 实现,以下是部分代码:

const DrawerNav = createDrawerNavigator();
const Drawer = ({ navigation }) => {
  return (
    <DrawerNav.Navigator>
      <DrawerNav.Screen name="MainStack" component={MainStack} />
      <DrawerNav.Screen name="OtherScreen" component={OtherScreen} />
    </DrawerNav.Navigator>
  );
};

const MainStackNav = createStackNavigator();
const MainStack = ({ navigation }) => {
  return (
    <MainStackNav.Navigator headerMode="none">
      <MainStackNav.Screen name="MainHome" component={HomeScreen} />
      <MainStackNav.Screen name="MainBottomTab" component={BottomTab} />
    </MainStackNav.Navigator>
  );
};

const BottomTabNav = createBottomTabNavigator();
const BottomTab = ({ navigation }) => {
  return (
    <BottomTabNav.Navigator>
      <BottomTabNav.Screen name="Home" component={HomeScreen}
        listeners={({ navigation }) => ({
        tabPress: (e) => {
          e.preventDefault();
          navigation.popToTop();
        },
      })}/>
      <BottomTabNav.Screen name="Stack1" component={Stack1} />
      <BottomTabNav.Screen name="Stack2" component={Stack2} />
      <BottomTabNav.Screen name="Stack3" component={Stack3} />
      <BottomTabNav.Screen name="Stack4" component={Stack4} />
      <BottomTabNav.Screen name="Stack5" component={Stack5} />
    </BottomTabNav.Navigator>
  );
};

1 个答案:

答案 0 :(得分:0)

即使这是可能的,您也应该避免在两个平台的人机界面指南 (iOS) 和体验中的抽屉内使用 Tab-Navigator。 TabBars 的特殊之处在于它们在更改活动屏幕时保持状态。它们应该显示您的应用程序的主要模块。如果您有其他上下文或屏幕(如登录等),您可以添加模态屏幕等。

抽屉是选项卡栏的替代主导航,您可以在其中拥有许多用户想要直接访问的项目(通常超过 5 个)。

我想要一个包含其他项目的菜单,您可以将它放在一个(最后一个)标签上并称之为“更多...”

关于你的另一个问题,结构不是那么复杂,我使用更复杂的结构没有问题。您只需要确保在更改结构时不会迷失自己,因此请尽量保持此代码的清洁。并确保您的用户不会在导航中丢失。