react-native页面的跳转

react-native的页面跳转

引言 :react-native出来也有一段时间了,一直只是听说react-nativa是如何的好,能够实现跨平台(android、IOS).一直没有去主动交接它。直到最近,公司为了节省后期的维护成本,也同时将现有的项目进行一次升级,然后决定用react-native重新开发一套。
当然了,接触一门新的技术难免会遇到很多的难点。根据实际开发遇到的问题写点文章。巩固自己的同时也许能帮到别人。
我学习的资料网[React Native 中文网](http://reactnative.cn/)
学习前期一些属性(props)、状态(state)、样式(style)、布局(flexbox)看着敲敲代码就能比较好接受了。
难点就是卡在页面的跳转了,虽然文档也提供了页面跳转的教程,但给我的感觉是一个页面自己在跳然后修改了一写属性值。(这并不能让我很满意,于是我就决定自己找资料写一个自己满意的)
[参考地址](http://blog.csdn.net/youth_never_go_away/article/details/52572029)

正题开始:先给大家上一组图(很惭愧,不会上传视频)。

第一个界面
第一个界面
点击跳转的图片
点击跳转的图片
点击跳转的图片
点击跳转的图片
注:在android。处于主界面时,支持双击返回退出。在其他页面时,支持点击返回回到上一个界面。
在实现界面跳转时需要提前了解的知识:

  1. navigater(导航器)
  2. scene(场景)
  3. route(路由)

    这三个概念也会在下面的代码中介绍到。

代码部分

程序的入口:index.ios.js

import React, { Component } from 'react';
import {
    AppRegistry,
} from 'react-native';
import SimpleComponent from './jsScene/SimpleComponent';

export default class helloRN extends Component {
  render() {
    return (
        //显示组件
        <SimpleComponent />    
    );
  }
}

AppRegistry.registerComponent('helloRN', () => helloRN);

入口代码非常简单,就是显示一个SimpleComponent的组件(不过你们要是照着敲时,注意文件夹的关系,这个很重要)
组件SimpleComponent.js

import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';
import FirstPageComponent from './FirstPageComponent';

export default class SimpleComponent extends Component {
  render() {
        //组件名字
        let defaultName = 'FirstPageComponent';
        //组件的Class用来实例化成<Component/>标签的
        let defaultComponent = FirstPageComponent;
        return (
            <Navigator
                //这个指定了默认的页面,也就是启动app之后会看到界面的第一屏。 需要填写两个参数: name 跟 component。
                //(注意这里填什么参数纯粹是自定义的,因为这个参数也是你自己发自己收,自己在renderScene方法中处理。
                // 我们这里示例用了两个参数,但其实真正使用的参数只有component)

                initialRoute={{ name: defaultName, component: defaultComponent }} //初始化场景

                //页面跳转动画  可以返回多个动画  使用||返回

                configureScene={(route) => {
                  return Navigator.SceneConfigs.HorizontalSwipeJump;    //设置场景的切换方式
                }}
                //渲染场景  route中就是我们自定义的 name 和 component
                //navigator 就是Navigator对象

                renderScene={(route, navigator) => {
                  let Component = route.component;

                  //Component 是route的component参数值  在路由中初始化的component的参数值是 defaultComponent
                  //所以 Component组件就是FirstPageComponent组件

                  return <Component {...route.params} navigator={navigator} />
                }} />
        );
    }
}

这段代码里面的内容就比较复杂了,我就每个关键字逐一解释,主要的内容是return()中的内容。
< Navigater />个人Navigater是所有组件的一个容器,所有的组件都会在Navigater中进行处理,后面会有代码进行很好的解释。
initialRoute={{ name: defaultName, component: defaultComponent }},这段代码是初始化一个路由,每一个页面以route为单位在Navigater中活动(显示或移除)

return Navigator.SceneConfigs.HorizontalSwipeJump; //界面的切换效果

    renderScene={(route, navigator) => {
                  let Component = route.component;

                  //Component 是route的component参数值  在路由中初始化的component的参数值是 defaultComponent
                  //所以 Component组件就是FirstPageComponent组件

                  return <Component {...route.params} navigator={navigator} />
                }}

这是最重要的一段代码,渲染一个场景,然后将渲染的场景(FirstPageComponent)返回(显示出来)。

组件FirstPageComponent.js

import React, { Component } from 'react';
import {
  View,
  StyleSheet,
  Navigator,
  Text,
  BackAndroid,
  TouchableOpacity
} from 'react-native'

//(MyToast是本人桥接的android的Toast。实际使用的过程可以直接去掉,以免报错)
import MyToast from './MyToast';

// // 下一句中的ToastAndroid即对应上文
// // public String getName()中返回的字符串
// // 练习时请务必选择另外的名字!
//
// export default NativeModules.ToastAndroid;
import SecondPageComponent from './SecondPageComponent';
import ThirdPageComponent from './ThirdPageComponent';
import FourthPageComponent from './FourthPageComponent';

export default class FirstPageComponent extends Component{
  constructor(props){
    super(props);
    this.state = {};
    this.firstClick = 0;
    this.handleBack = this.handleBack.bind(this);
  }

  //生命周期方法。在组建第一次绘制完成后调用,通知组建已经加载完成。
  componentDidMount () {
    BackAndroid.addEventListener('hardwareBackPress', this.handleBack)  //增加手机物理返回键的监听
  }

  //生命周期方法。组建被移除时调用此方法
  componentWillUnmount () {
    BackAndroid.removeEventListener('hardwareBackPress', this.handleBack)   //增加手机物理返回键的监听
  }

//双击返回键退出
handleBack(){
    const { navigator } = this.props;
    if (navigator && navigator.getCurrentRoutes().length > 1) {
      navigator.pop();
      return true;
    }else{
      let timestamp = (new Date()).valueOf();
      if(timestamp - this.firstClick > 2000){
        MyToast.show('在按一次退出',MyToast.SHORT);
        this.firstClick = timestamp;
        return true;
      }else{
        return false;
      }
    }
  }

  //页面的跳转
  _pressButton(index){
    const { navigator } = this.props;
    if (navigator){
      switch (index) {
        case 2:
          navigator.push({
            name:'SecondPageComponent',
            component:SecondPageComponent,
          });
          break;
        case 3:
          navigator.push({
            name:'ThirdPageComponent',
            component:ThirdPageComponent,
          });
          break;
        case 4:
          navigator.push({
            name:'FourthPageComponent',
            component:FourthPageComponent,
          });
          break;
        default:
        break;
      }
    }
  }

  render(){
    return(
      <View>
        <TouchableOpacity onPress={this._pressButton.bind(this,2)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到2
            </Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._pressButton.bind(this,3)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到3
            </Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._pressButton.bind(this,4)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到4
            </Text>
        </TouchableOpacity>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  red:{
    fontSize:40,
    fontWeight:'300',
    color:'red'
  }
});

还是先从主要的方法说起

return(
      <View>
        <TouchableOpacity onPress={this._pressButton.bind(this,2)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到2
            </Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._pressButton.bind(this,3)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到3
            </Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._pressButton.bind(this,4)}
                          style={{ flexDirection:'row', alignItems:'center' }}>
            <Text style={styles.red}>点我跳转到4
            </Text>
        </TouchableOpacity>
      </View>
    )

这只是基本的排列,主要要解释是的是this._pressButton.bind(this,4)方法。这就是点击事件调用_pressButton(index)方法,index是this后面的参数,接下来看方法

_pressButton(index){
    const { navigator } = this.props;
    if (navigator){
      switch (index) {
        case 2:
          navigator.push({
            name:'SecondPageComponent',
            component:SecondPageComponent,
          });
          break;
        case 3:
          navigator.push({
            name:'ThirdPageComponent',
            component:ThirdPageComponent,
          });
          break;
        case 4:
          navigator.push({
            name:'FourthPageComponent',
            component:FourthPageComponent,
          });
          break;
        default:
        break;
      }
    }
  }

在这段代码中有一个难以理解的地方就是navigater对象是哪里来的?
回到simplePageComponent.js中

return < Component {…route.params} navigator={navigator} />

在返回时返回了一个navigator对象的属性

* const { navigator } = this.props; *
这里就获取到了。

navigator.push({
            name:'ThirdPageComponent',
            component:ThirdPageComponent,
          });

这段代码就是将ThirdPageComponent组件放入navigator的栈中。达到显示的目的。
ThirdPageComponent.js方法中就比较简单了

import React, { Component } from 'react';
import {
  View,
  StyleSheet,
  Navigator,
  Image,
  Dimensions,
  Text,
  TouchableOpacity
} from 'react-native'

var deviceWidth = Dimensions.get('window').width;

const BANNER_IMGS = [
    require('../imgs/meinv2.png'),
    require('../imgs/meinv3.png'),
    require('../imgs/meinv4.png'),
    require('../imgs/meinv2.png')
];

export default class ThirdPageComponent extends React.Component {
    constructor(props) {
        super(props);
        this._pressButton = this._pressButton.bind(this);
    }

    _pressButton() {
        //获取SampleComponent中创建的Navigator对象
        const { navigator } = this.props;
        //为什么这里可以取得 props.navigator?请看上文:
        //<Component {...route.params} navigator={navigator} />
        //这里传递了navigator作为props
        //这里对navigator进行了判断  如果navigator(导航器)对象存在的情况下 在进行操作
        if (navigator) {
            navigator.pop();
        }
    }

    _renderPage(data, pageID) {
        return (
            <Image
                source={data}
                style={styles.page}/>
        );
    }

    //创建点击区域 当点击的时候 进行 页面的跳转 也就是对navigator的参数进行设置  使其跳转到 第二个界面
    render() {
        return (
            <View >
                <TouchableOpacity onPress={this._pressButton.bind(this)}
                                  style={{flexDirection:'row' ,alignItems: 'center'}}>
                    <Text style={styles.red}>点我跳回去</Text>
                </TouchableOpacity>
                <Text style={styles.red}>我是第三页面</Text>
            </View>
        );
    }
}
const styles=StyleSheet.create({
    red:{
        fontSize:40,
        fontWeight:'bold',
        color:'red'

    },
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'flex-start',
        paddingTop:5,
        paddingLeft:5,
        backgroundColor:'#999999',
        paddingRight:5,
        paddingBottom:5,
    },
    page: {
        width: deviceWidth,//设备宽(只是一种实现,此处多余)
        flex: 1,
        height: 130,
        resizeMode: 'stretch'
    },
});

这个组件中只有一个重要代码

navigator.pop();    //返回上一个组件

恩!到此为止,一个react-native的原生的页面的跳转就完成,还加入一些返回的细节。(MyToast是桥接的android的Toast。实际使用的过程可以直接去掉,以免报错)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值