博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用react-native中的Navigator组件进行页面导航

Posted on 2015-10-27 11:29  三块石头  阅读(26693)  评论(3编辑  收藏  举报

最近对React比较感兴趣,然后爱屋及乌,也研究了下React-Native, 后面简称为RN。

RN刚发布时,Facebook官方说为了快速发布,我们暂时只支持在MacOS上使用, 其他操作系统会慢慢支持。这可让那些用不起Mac的程序员苦逼了。。还好还好,最近RN发布了0.13.0版本了,已经兑现了对windows的支持,所以广大的程序猿们可以在windows上利用RN开发Android应用啦。。至于开发iOS应用,呵呵,还是不要想了,调试还是需要模拟器的嘛。。关于Android环境的搭建可以参考

Windows下搭建React Native Android开发环境》一文,不过作者提到需要修改react-native里面的代码就不必要了,因为那些问题都已经修正了。所以你就大胆的使用的。就几句话:

npm install react-native-cli -g   #安装react-native控制台工具

react-native init AwesomeProject #初始化一个项目

react-native start  #运行服务,用于生成js bundle

ract-native run-android #在手机上或者模拟器上运行android应用

 

废话少说,进入我们今天的主题:如果在RN中使用Navigator。 首先的问题是:何为Navigator?  从字面意思上来说,就是导航了。通俗点讲,就是说一个页面跳转到另外一个页面,相当于是页面的控制器。如果大家稍微熟悉下Android的开发,就知道,在Android中一个页面就是一个Activity,然后通过Intent,我们可以跳转到另外一个Activity。我们想要的就是这种效果。那我们该怎么办呢?

 

参考RN的官方文档, 我们知道有Navigator这么一个玩意,但是官方文档比较晦涩,不知道写的些啥,所以还是自己慢慢google吧,苦逼呀。。。

 

找了一圈,终于有点眉目,其实还是比较简单的,我们看一个render方法:

    render() {
        return (
            <Navigator
                initialRoute={{name: 'welcome'}}
                configureScene={this.configureScene}
                renderScene={this.renderScene} />
        );
    }

上面代码里面的 Navigator就是控制页面跳转的,像一个路由的似的,可以控制页面的流转。但是其他属性都是些什么玩意?我来一个一个分析说明。

 

initialRouter: 路由初始化配置信息,就是说页面加载时,第一次需要展现什么内容

configureScene: 场景转换动画配置。在RN看来,从一个页面切换到另外一个页面,就是从一个场景切换到另外一个场景,这里配置的是场景动画信息,比如Navigator.SceneConfigs.FadeAndroid 就是淡入淡出

renderScene: 渲染场景,读取initialRouter传来的数据,确定显示那些内容。

我们上代码:


var React = require('react-native');
var {
  AppRegistry,
  View,
  Navigator,
  Text,
  BackAndroid,
  StyleSheet
} = React;

 


var
SampleApp = React.createClass({ configureScene(route){ return Navigator.SceneConfigs.FadeAndroid; }, renderScene(router, navigator){ var Component = null;this._navigator = navigator; switch(router.name){ case "welcome": Component = WelcomeView; break; case "feed": Component = FeedView; break; default: //default view Component = DefaultView; } return <Component navigator={navigator} /> }, componentDidMount() { var navigator = this._navigator; BackAndroid.addEventListener('hardwareBackPress', function() { if (navigator && navigator.getCurrentRoutes().length > 1) { navigator.pop(); return true; } return false; }); }, componentWillUnmount() { BackAndroid.removeEventListener('hardwareBackPress'); }, render() { return ( <Navigator initialRoute={{name: 'welcome'}} configureScene={this.configureScene} renderScene={this.renderScene} /> ); } });

AppRegistry.registerComponent('AwesomeProject', () => SampleApp);

 

从代码可以看到, initialRouter传入的是{name:'welcome'}, 然后configureScene返回的是 Navigator.SceneConfigs.FadeAndroid,表示从一个页面切换到另外一个页面时,动画效果是淡入淡出。然后最重要的是renderScene, 组件会这给这个函数传入两个参数,一个是router,路由信息;另外一个navigator对象。 我们可以通过router里面的数据来渲染指定的内容。其他View代码如下所示:

 

var FeedView = React.createClass({
    goBack(){
      this.props.navigator.push({name:"default"});
    },

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome} onPress={this.goBack} >
                    I am Feed View! Tab to default view!
                </Text>
            </View>  
        )
    }
});


var WelcomeView = React.createClass({
    onPressFeed() {
        this.props.navigator.push({name: 'feed'});
    },


    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome} onPress={this.onPressFeed} >
                    This is welcome view.Tap to go to feed view.
                </Text>
            </View>
        );
    }

});

var DefaultView = React.createClass({

    render(){
      return (
          <View style={styles.container}>
              <Text style={styles.welcome}>Default view</Text>
          </View>
      )
    }
});

 

从一个页面跳转到另外一个页面如何实现?  很简单,在renderScene方法中,我们渲染组件时,给组件传递了一个navigator属性,在组件中调用 this.props.navigator.push就可以跳转到指定的页面。注意传入的参数。调用this.props.navigator.push方法,  renderScene会再次执行,然后渲染对应的组件。  如果希望返回上一个页面,调用 this.props.navigator.pop即可。

 

完整的代码可以访问 https://gist.github.com/flyingzl/3188e8e5dfa49e68432b

 

效果预览访问 https://rnplay.org/apps/D4QP9A