美文网首页ReactNativeReact-Native前端xuexi
翻译|React-navigation导航系统(1)

翻译|React-navigation导航系统(1)

作者: smartphp | 来源:发表于2017-03-27 23:21 被阅读9366次

    title: 翻译|React-navigation(1)
    date: 2017-03-27 20:26:48
    categories: 翻译


    这个React-native的导航系统可能已经基本官方标配系统了.两个月时间已经积累了3000多的star.
    教程可以参考这篇文章,这个文章作者老兄和我一样很喜欢折腾.前面就参考了他的另一个导航教程,这次再来.


    本文是翻译的官方文档.打算翻译完
    基本思路是有几个注册系统,如果要在app中使用导航,必须要把组件注册到对应的系统中.

    原文开始:你好!移动导航

    使用React Navigation来构建跨平台导航

    配置和安装

    首先要配置React Native系统.接下来创建RN项目,添加react-navigation

     # Create a new React Native App
     #创建新RN APP
    react-native init SimpleApp
    cd SimpleApp
    
    # Install the latest version of react-navigation from npm安装最新版本
    npm install --save react-navigation
    
    # Run the new app运行,确保初始化正常
    react-native run-android # or:
    react-native run-ios
    
    初始化界面初始化界面

    为了在Android和iOS之间共享代码,删除掉index.ios.jsindex.andorid.js的实际代码,使用import './App'来实现具体的代码

    现在来创建‘App.js’

    Stack Navigator介绍

    为了想使用stack navigation的概念,我们会使用StactkNavigator.(译注:stack就是数据结构的堆栈技术,遵循后进先出的原理).每一个到导航的screen(导航画面)被放在堆栈的栈顶,返回时候,会从栈顶弹出对应的组件.先看看一个screen的情况

    //其实这个代码没有实现App.js,export的模式,注意
    import React from 'react';
    import {
      AppRegistry,
      Text,
    } from 'react-native';
    //导入stack导航组件
    import { StackNavigator } from 'react-navigation';
    
    class HomeScreen extends React.Component {
      static navigationOptions = {
        title: 'Welcome',//在导航中显示的标题内容
      };
      render() {
        //这里可以是导入的其他组件
        return <Text>Hello, Navigation!</Text>;
      }
    }
    //进行导航的注册
    const SimpleApp = StackNavigator({
      Home: { screen: HomeScreen },
    });
    
    AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
    

    title是staticnavigationOptions里配置的标题内容,出现的界面看下面

    添加新的导航画面

    再添加一个ChatScreen画面

     class ChatScreen extends React.Component {
      static navigationOptions = {
        title: 'Chat with Lucy',
      };
      render() {
        return (
          <View>
            <Text>Chat with Lucy</Text>
          </View>
        );
      }
    }
    

    HomeScreen中添加一个button组件,使用routeName Chat关联到ChatScreen.

     class HomeScreen extends React.Component {
      static navigationOptions = {
        title: 'Welcome',
      };
      render() {
        const { navigate } = this.props.navigation;
        return (
          <View>
            <Text>Hello, Chat App!</Text>
            <Button
              onPress={() => navigate('Chat')}
              title="Chat with Lucy"
            />
          </View>
        );
      }
    }
    

    我们正在使用从screen navigation prop获得的导航函数转向ChatScreen.但是这需要在StackNavigator中注册.

     const SimpleApp = StackNavigator({
      Home: { screen: HomeScreen },
      Chat: { screen: ChatScreen },//新添加的screen
    });
    
    

    现在可以导航到ChatScreen,也可以返回了.


    传递参数

    ChatScreen中硬编码标题不是好办法,可以在导航的时候传递参数.首先编辑一下HomeScreen组件,传递name参数到路由中.

     class HomeScreen extends React.Component {
      static navigationOptions = {
        title: 'Welcome',
      };
      render() {
        const { navigate } = this.props.navigation;
        return (
          <View>
            <Text>Hello, Chat App!</Text>
            <Button
              onPress={() => navigate('Chat', { user: 'Lucy' })}
              title="Chat with Lucy"
            />
          </View>
        );
      }
    }
    

    我们可以编辑ChatScreen组件显示的name参数,这个参数通过route来传递.

     class ChatScreen extends React.Component {
      static navigationOptions = {
        // Nav options can be defined as a function of the navigation prop:
        title: ({ state }) => `Chat with ${state.params.user}`,
      };
      render() {
        // The screen's current route is passed in to `props.navigation.state`:
        const { params } = this.props.navigation.state;
        return (
          <View>
            <Text>Chat with {params.user}</Text>
          </View>
        );
      }
    }
    
    

    现在当你导航到Chat screen的时候,可以看到名字了.在HomeScreen中改变name,看看变化.

    巢式导航

    在移动应用中组合各种形式的导航是非常普遍的.React Navigation中的router和navigators是组合式的,如此以来可以允许我们定义非常复杂的导航系统.

    Tab Navigator的介绍

    我们在App.js中创建TabNavigator

     class RecentChatsScreen extends React.Component {
    render() {
      return <Text>List of recent chats</Text>
    }
    }
    
    class AllContactsScreen extends React.Component {
    render() {
      return <Text>List of all contacts</Text>
    }
    }
    
    const MainScreenNavigator = TabNavigator({
    Recent: { screen: RecentChatsScreen },
    All: { screen: AllContactsScreen },
    });
    

    如果MainScreenNavigation作为顶层的导航组件来渲染,看起来是这个样子的:

    在屏幕中构造一个巢式导航器

    我们想让这些tabs在app的第一屏显示,但是堆栈中的新的screen会覆盖tabs.
    在前一步骤设置的StackNavigator中添加tabs作为顶级导航

     const SimpleApp = StackNavigator({
      Home: { screen: MainScreenNavigator },
      Chat: { screen: ChatScreen },
    });
    

    因为MainScreenNavigator作为screen,可以传递navigationOtions参数:

     MainScreenNavigator.navigationOptions = {
      title: 'My Chats',
    };
    

    在每一个tabs中添加链接到chat的按钮:

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

    现在我们在每个导航器彼此之间做了配置,可以在导航界面之间切换.

    配置头部

    在前面的例子中,我们用StactNavigator创建了几个screen.
    当我们导航到chat screen,我们通过navigate 函数传递特定的参数到新的导航界面.例如,我们想给chat screen提供一个人名:

     this.props.navigation.navigate('Chat', { user:  'Lucy' });
    

    user参数可以在chat screen中获取到:

     class ChatScreen extends React.Component {
      render() {
        const { params } = this.props.navigation.state;
        return <Text>Chat with {params.user}</Text>;
      }
    }
    
    

    设定头部标题

    接着来,可以在screen 参数中配置头部的标题

     class ChatScreen extends React.Component {
      static navigationOptions = {
        // // Title may be a simple string:
        // title: 'Hello',
         
        // Or the title string may be a function of the 
        navigation prop:可以是prop的函数解析
        title: ({ state }) => `Chat with ${state.params.user}`
      };
      ...
    }
    

    添加右侧的按钮

    可以在option中添加定制的右侧按钮

    static navigationOptions = {
      header: {
        right: <Button title="Info" />,
      },
      ...
    

    title一样,headeroption可以定义为prop的一个函数.让我们来基于导航参数渲染一个不同的按钮,设定为点击时调用navigation.setParams:

    static navigationOptions = {
      title: ({ state }) => {
        if (state.params.mode === 'info') {
          return `${state.params.user}'s Contact Info`;
        }
        return `Chat with ${state.params.user}`;
      },
      header: ({ state, setParams }) => {
        // The navigation prop has functions like setParams, goBack, and navigate.
        let right = (
          <Button
            title={`${state.params.user}'s info`}
            onPress={() => setParams({ mode: 'info' })}
          />
        );
        if (state.params.mode === 'info') {
          right = (
            <Button
              title="Done"
              onPress={() => setParams({ mode: 'none' })}
            />        
          );
        }
        return { right };
      },
      ...
    

    现在头部可以和screen的路由state进行交互了.



    第一部分就这些.

    相关文章

      网友评论

      • 三文治z:学习了!
      • 爱吃板栗的小女孩:你好,请假一下onpress时候怎么可以先关闭界面,然后跳转新页面?
        初学,谢谢
      • 3a601209eff1:你好,请问<TouchableOpacity onPress={() => this.props.navigation.navigate('Detail')}>,跳转不过去,点击后没有反应。Detail已经添加到StackNavigator中。
      • Bel李玉:楼主 你好 我执行完 npm install --save react-navigation之后项目就不能运行了报
        Make sure that you have run `npm install` and that you are inside a react-native project错误,请问怎么回事
      • 瘦胖纸_a0bb:请问在 Navigate 内页,如何跳出Navigate 内的 tab 。原本是在Navigate 页之前有一个登陆页。是根据state做了跳转, 跳到 Navigate 里的内页后如何跳出来回到登陆页?是否可按原思路改变state 跳回 ?
      • 李乾坤David:紧需之时看到!
      • 30aa8f21984f:try replacing the following {title:({state})=>state...} with (navigation)=>({title:navigation.state})
        上面是用您的方法后报错的,该如何解决呢?还是说用下面的替换?
        Atzcl:使用官方文档的
        static navigationOptions = ({ navigation }) => ({
        title: `我是 ${navigation .state.params.user}`
        });
        即可
      • smartphp:这个你看一下第二部分的嵌套导航部分的问题。scroll-tab-view里的组件要嵌套到堆栈导航里面,要不然导航系统不知道你要干什么。思路就是这样的。我也没机会用这个东西,具体的问题还要你自己分析,如果可以放到github上,我看看能不能解决。
      • 张大娃创业笔记:我想问一下,为何我用react navigation做的tabbar然后首页里面使用react-native-scrollview-tab却不能显示对应的页面呢,又没报错还可以滑动,就是不显示页面内容,只有打开一个新页面返回后才能显示,所以我想请教一下大师知道怎么解决吗?
      • Juice_gg:楼主,什么时候翻译一下结合redux使用的那一部分啊
        Juice_gg:@smartphp 现在正在看那一部分,有点懵逼,,,,,
        smartphp:嗯,争取快一点.也是边看边翻.
      • smartphp:图片用的是图床的图片所有大小不好定义,hexo和简书不好兼顾啊

      本文标题:翻译|React-navigation导航系统(1)

      本文链接:https://www.haomeiwen.com/subject/sdydottx.html