React-native 尝鲜计划-场景切换(Navigator)
来源:互联网 发布:同志电影app软件 编辑:程序博客网 时间:2024/06/07 02:48
在上篇文章《react-native 尝鲜计划-环境搭建》中讲述了react-native 的环境搭建,并初始化了 react-native 的第一个项目。如果你已经完成了上一篇文章的学习,并且成功调试第一个 “hello world” 项目,你已成功地经迈出第一步,接下来的学习就会顺利得多。在我成功调试出第一个项目之后,连蒙带差的走读了下原生代码和 index.android.js 代码,脑海里有很多疑问,第一个疑问就是:react-native 如何做多个页面跳转的?相信你也一样,带着带着问题来学习是比较有动力的一种学习方式。
- 切换场景demo
本章重点是 demo,react-native场景切换的demo下载地址:https://github.com/liuguangli/RN-DemoForChangeSence。
先跑出效果,从现象到本质符合人类的一般认知规律,建议读者下载demo自行研究,我也希望你研究demo之后不用读后文了。
- Navigator 热身
react-natvie 中来切换页面的一个重要组件就是Navigator,这里只介绍demo中用到的几个重要的属性和方法,详细的可以点击这里可以看官方文档介绍。
1 initialRoute
Navigator 的一个属性,用来描述Navigator场景栈中的第一个场景信息route。一个结构类型,一个般要提供 name,index等描述信息。
2 renderSence
Navigator 的一个方法,在Navigator创建或 push(route) /pop()方法调用的时候回调renderSence(route, navigator)方法,出入两个参数:route和 navigator 本身。
3 push
场景跳转:指定一个route, 在回调方法 renderSence()中根据 route 返回指定的 sence,sence可以是任何可视化组件或容器。
4 pop
回退到上一个场景。
- 一步一步的来实现这个demo
1. 入口(index.android.js)
我们先完成 react 的第一个入口组件,将其注册到到 app上。
首先引入我们要使用的组建:
var React = require('react-native');var { AppRegistry, Navigator,} = React;
AppRegistry,用于注册我们的程序入口组件。Navigator,是我们使用的第一个组件,用于操作场景转换。
创建组件:
// 创建入口组件var ChangeSenceProject = React.createClass({ render: function() { var initialRoute = {name:"A"}; return (<Navigator initialRoute={initialRoute} renderScene={RouteMapper} />) },});注册到应用:
//注册项目AppRegistry.registerComponent('ChangeSenceProject', () => ChangeSenceProject);注意到我们在 ChangeSenceProject 的入口方法 render 中使用 Navigator 组件,并且提供第一个route对象:{name:"A"}和一个renderSence方法,这个方法必须要实现,所以我们要在React.createClass之前先实现renderSence方法,我们方法名定义为:RouteMapper
//Navigator跳转规则var RouteMapper = function(route,navigation,onComponent){ //todo ,根据route 返回相应的场景};
这里我门不实现逻辑,等我门完成两个场景页面的编写再来实现这里的逻辑。
2. Android native
我们使用 ReactRootView 来承载我们的交互组件。
main_activity.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MoviesApp"> <com.facebook.react.ReactRootView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/react_root_view"/></RelativeLayout>MainActivity.java
package com.changesence;import android.app.Activity;import android.os.Bundle;import android.view.KeyEvent;import com.facebook.react.LifecycleState;import com.facebook.react.ReactInstanceManager;import com.facebook.react.ReactRootView;import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;import com.facebook.react.shell.MainReactPackage;public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { private ReactInstanceManager mReactInstanceManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(true) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); ((ReactRootView) findViewById(R.id.react_root_view)) .startReactApplication(mReactInstanceManager, "ChangeSenceProject", null); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onPause(); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onResume(this); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); }}
注意:startReactApplication()方法的第一个参数必须和我们在 AppRegistry 中注册的项目名一样。
到此为止,项目可以运行起来了,不过你看到的是空白页面,因为RouteMapper还没有任何实现,我们需要提供场景逻辑。
3 . 场景A(SenceA.js)
在场景A中我们只做简单的显示一行文字,然后点击文字跳转到场景B。
直接上代码:SenceA.js
'use strict';var React = require('react-native');var { TouchableNativeFeedback, Navigator, StyleSheet, Text, View,} = React;var SenceA = React.createClass({ //touch事件回调 touch: function(target:Object){ this.props.navigator.push( { title:"B", name:"B" } ); }, render: function() { return (<View style={styles.container}> <TouchableNativeFeedback onPress={this.touch}> <View> <Text>' this is SenceA,click to SenceB'</Text> </View> </TouchableNativeFeedback> </View>); },});var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', },});//导出场景,供外部requiremodule.exports = SenceA;
4 场景B
场景比和场景A一样,显示内容不一样。直接上代码:SenceB.js
'use strict';var React = require('react-native');var { TouchableNativeFeedback, Navigator, StyleSheet, Text, View,} = React;var SenceB = React.createClass({ touch: function(target:Object){ if (this.props.navigator.getCurrentRoutes().length>1) { this.props.navigator.pop(); }; }, render: function() { return (<View style={styles.container}> <TouchableNativeFeedback onPress={this.touch}> <View> <Text>' this is sence B,click to sence A'</Text> </View> </TouchableNativeFeedback> </View>); },});var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#FFFC00', },});module.exports = SenceB;5 在 index.android.js 引入场景,完善RouteMapper逻辑。
引入场景:
//引入场景文件var SenceA = require('./SenceA');var SenceB = require('./SenceB');完善RouteMapper:
//Navigator跳转规则var RouteMapper = function(route,navigation,onComponent){ _navigator = navigation; if (route.name === 'A') { console.log("return SenceA"); return ( <SenceA navigator={navigation} /> ); } else if (route.name==="B"){ console.log("return SenceB"); return ( <SenceB navigator={navigation} /> ); } };
- 武器准备
如果 react-navtive 是移动应用开发的另一个战场的话,那么走到这里我们算是已经知道战场在哪里了,接下来事就是怎么操练武器了。要熟悉react-native的编程,我门先要掌握以下武器:
1 js基础
2 node.js
3 jsx 语法
4 flexbox布局
注:react-native 出来不久文档资料不多,文章不足之处欢迎指正,一起研究新技术、新思想。
- React-native 尝鲜计划-场景切换(Navigator)
- 【REACT NATIVE 系列教程之八】不使用NAVIGATOR实现切换(页面)场景的两种形式(逻辑与MODAL)
- React-Native尝鲜计划-环境搭建及 hello world
- React Native学习笔记(4)--Navigator
- React Native Android(二)Navigator知识点
- react-native navigator
- react-native--Navigator
- React Native之Navigator
- React Native[Navigator]
- React-Native之Navigator
- react-native navigator
- react-native-tab-navigator
- React Native Navigator
- react native Navigator
- React Native Navigator
- React-native navigator
- React Native 实现基于react-native-tab-navigator库Tab切换封装
- React Native]React Native组件之Navigator
- pat-1009
- 【C++】判断顺序栈出栈顺序的合法性
- HTML5游戏制作之路_09_egret的Timer
- android studio mvvm
- 线程中的的资源(二)
- React-native 尝鲜计划-场景切换(Navigator)
- 阻塞
- 前端必读:浏览器内部工作原理
- C-7.指针
- javascript闭包和函数块作用域
- [iOS]添加 All Exceptions 断点后, 每次运行都会在 main.m 中断的一种解决方法
- 在FastReport2.8中打开frf文件,选择另存为fr3文件,这时FastReport4是不能打开该文件的。按下述步骤调整:
- C语言二叉树的遍历,递归和非递归
- 用root直接登入Ubuntu 14.04