Nesting Navigators - 导航器的嵌套

在移动应用程序中,组合形式的导航是很常见的。React Navigation中的路由和导航器可以组合在一起,可以让你为你的app定义复杂的导航结构。

对于我们的聊天应用程序,我们希望在第一个屏幕上放置几个标签,查看最近的聊天会话或所有联系人。

Tab Navigator简介

首先,在App.js文件中新建一个TabNavigator

  1. import { TabNavigator } from "react-navigation";
  2. class RecentChatsScreen extends React.Component {
  3. render() {
  4. return <Text>List of recent chats</Text>
  5. }
  6. }
  7. class AllContactsScreen extends React.Component {
  8. render() {
  9. return <Text>List of all contacts</Text>
  10. }
  11. }
  12. const MainScreenNavigator = TabNavigator({
  13. Recent: { screen: RecentChatsScreen },
  14. All: { screen: AllContactsScreen },
  15. });

如果MainScreenNavigator渲染为顶层的导航器组件,那它看上去会像这样:


Nesting Navigators - 导航器的嵌套 - 图1 Nesting Navigators - 导航器的嵌套 - 图2


将导航器嵌套在页面中

我们希望这些tabs只在app的第一个页面中可见,当跳转新页面时,路由栈中的新页面可以覆盖这些tabs。

将带有tabs的导航器作为一个页面,添加到我们前面设置过的StackNavigator的顶部,

  1. const SimpleApp = StackNavigator({
  2. Home: { screen: MainScreenNavigator },
  3. Chat: { screen: ChatScreen },
  4. });

因为MainScreenNavigator将被作为一个页面使用,所以我们可以给它设置navigationOptions属性。

  1. const SimpleApp = StackNavigator({
  2. Home: {
  3. screen: MainScreenNavigator,
  4. navigationOptions: {
  5. title: 'My Chats',
  6. },
  7. },
  8. Chat: { screen: ChatScreen },
  9. })

让我们也为每个tab添加一个按钮,都可以跳转到Chat页面:

  1. <Button
  2. onPress={() => this.props.navigation.navigate('Chat', { user: 'Lucy' })}
  3. title="Chat with Lucy"
  4. />

现在我们已经把一个导航器放在另一个导航器中,并且我们可以在导航器之间切换:


Nesting Navigators - 导航器的嵌套 - 图3 Nesting Navigators - 导航器的嵌套 - 图4


在组件中嵌套导航器

有时需要对包含在组件中的导航器进行嵌套。这在导航器只占用屏幕一部分的情况下非常有用。为了将子导航器连接到导航树中,子导航器需要使用父导航器的navigation属性。

  1. const SimpleApp = StackNavigator({
  2. Home: { screen: NavigatorWrappingScreen },
  3. Chat: { screen: ChatScreen },
  4. });

在这种情况下,NavigatorWrappingScreen不是一个导航器,它只是将导航器作为其渲染的一部分。

  1. class NavigatorWrappingScreen extends React.Component {
  2. render() {
  3. return (
  4. <View>
  5. <SomeComponent/>
  6. <MainScreenNavigator/>
  7. </View>
  8. );
  9. }
  10. }

如果上述代码运行后,界面是空白,就把<View>改成<View style={{flex: 1}}>

接下来,把MainScreenNavigator连接到导航树中,我们将它的router赋值给wrapping组件,即:NavigatorWrappingScreen。这将使NavigatorWrappingScreen感知导航动作,告诉父导航器向下传递导航对象。由于NavigatorWrappingScreenrouter被子导航器的router覆盖,子导航器将接收到想要的导航事件。

  1. class NavigatorWrappingScreen extends React.Component {
  2. render() {
  3. return (
  4. <View>
  5. <SomeComponent/>
  6. <MainScreenNavigator navigation={this.props.navigation}/>
  7. </View>
  8. );
  9. }
  10. }
  11. NavigatorWrappingScreen.router = MainScreenNavigator.router;