之前我们介绍了RN相关的知识:

是时候了解React Native了

从零学React Native之01创建第一个程序

从零学React Native之02状态机

本篇主要介绍页面导航

上一篇文章给大家介绍了简单界面的搭建, 这一篇我们需要两个界面, 一个是注册界面,一个是注册信息界面. 当然我们还需要一个组件去控制两个界面的切换.

每个界面其实就一个组件 , 可以通过下面的代码抽取相关的模块

module.exports=RegisterLeaf;

注册界面的代码:

主要代码


import React, { Component } from 'react';
import {
AppRegistry, //框架提供的API
StyleSheet,
Text, // RN提供的组件
View,
TextInput // 记得引入组件
} from 'react-native';
//let是更完美的var
let Dimensions = require('Dimensions');// 宽高
let totalWidth = Dimensions.get('window').width; //声明了三个变量,根据屏幕动态变化
let leftStartPoint = totalWidth * 0.1;
let componentWidth = totalWidth * 0.8; class RegisterLeaf extends Component { //构造函数, 组件创建的时候会执行
constructor(props) {
super(props); //必须有这句代码 父组件向子组件传递属性, 比如styles属性等
// 声明状态机的初始值
this.state = {
inputedNum: '',
inputedPw: ''
};
// ES6中使用的方法需要绑定this, 否则方法中不能使用this
this.userPressConfirm=this.userPressConfirm.bind(this);
}
// 定义函数
updateNum(newText) {
this.setState((state)=> {
return {
inputedNum: newText
}
});
}
// 定义函数
updatePW(newText) {
this.setState(()=> { // 用不到的参数也可以不用写
return {
inputedPw: newText
}
});
}
userPressConfirm(){
console.log("userPressConfirm");
this.props.navigator.push({
phoneNumber:this.state.inputedNum,
userPW:this.state.inputedPw,
name:'waiting'
})
}
// 绘制渲染的控件
render() {
return (
/*(newText)=>this.updateNum(newText)
它将收到的字符串为参数调用当前组件的updateNum函数,并且将updateNum函数的返回值返回
当前函数在输入框文本变化的时候会调用
语句可以改成
this.updateNum
但一定不要写成
this.updateNum(newText) 因为有右箭头函数的时候newText是形式参数
没有箭头函数的时,newText就没有定义
*/
<View style={styles.container}>
<TextInput style={styles.numberInputStyle}
keyboardType={'phone-pad'}
placeholder={'请输入手机号'}
onChangeText={(newText)=>this.updateNum(newText)}/> <Text style={styles.textPromptStyle}>
您输入的手机号:{this.state.inputedNum}
</Text>
<TextInput secureTextEntry={true}
style={styles.passwordInputStyle}
placeholder='请输入密码'
onChangeText={(newText)=>this.updatePW(newText)}/>
<Text style={styles.bigTextPrompt}
onPress={this.userPressConfirm}>
注 册
</Text>
</View>
);
}
}
// 样式 const变量只能在声明的时候赋值一次
const styles = StyleSheet.create({
//各个组件都没有定义高度,父View设置了flex1,他会沾满整个高度,子组件没有设置会包裹内容
container: {
flex: 1, //表示宽高会自动扩展
backgroundColor: 'white'
},
numberInputStyle: {
top: 20, // top left表示从父组件的顶端(左侧) 向下(向右) 多少位置显示
left: leftStartPoint,
// height:30, // IOS开发需要加上该高度
width: componentWidth,
backgroundColor: 'gray',
fontSize: 20
},
textPromptStyle: {
top: 30,
left: leftStartPoint,
// // height:30, // IOS开发需要加上该高度 因为IOS中TextInput不会自动设置高度
width: componentWidth,
fontSize: 20
},
passwordInputStyle: {
top: 50,
left: leftStartPoint,
width: componentWidth,
backgroundColor: 'gray',
fontSize: 20
},
bigTextPrompt: {
top: 70,
left: leftStartPoint,
width: componentWidth,
backgroundColor: 'gray',
color: 'white',
textAlign: 'center',//位置居中显示
fontSize: 60
}
});
module.exports=RegisterLeaf;

注册展示信息的代码

import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native'; class WaitingLeaf extends Component {
constructor(props) {
super(props);
this.goBack=this.goBack.bind(this);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.textPromptStyle}>
注册使用的手机号:{this.props.phoneNumber}
</Text>
<Text style={styles.textPromptStyle}>
注册时使用的密码:{this.props.userPW}
</Text>
<Text style={styles.bigTextPrompt}
onPress={this.goBack}>
返回
</Text>
</View>
);
}
// 会调用 index.js 中模块renderScene方法 渲染RegisterLeaf
//push函数像是Navigator组件在原来的屏幕上新放了一张纸,replace像是把原来的纸拿下来放了一张新的纸
goBack(){
this.props.navigator.replace({
name:"register"
})
}
} const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
textPromptStyle: {
fontSize: 20
},
bigTextPrompt: {
width: 300,
backgroundColor: 'gray',
color: 'white',
textAlign: 'center',
fontSize: 60
}
}); module.exports = WaitingLeaf;

界面效果:

主View 代码

import React, { Component } from 'react';
import {
AppRegistry, //框架提供的API
Navigator,
BackAndroid
} from 'react-native';
let RegisterLeaf = require('./RegisterLeaf');
let WaitingLeaf = require('./WaitingLeaf'); class NaviModule extends Component {
constructor(props){
super(props);
//返回一个绑定好this的方法并存储于当前实例中
this.handleBack=this.handleBack.bind(this);
}
//告知Navigator 模块切换时的效果, 名字要和Navigator组件的configureScene保持一致
configureScene(route) {
return Navigator.SceneConfigs.FadeAndroid;
} // 告知Navigator模块我们希望如何挂接当前的视图 函数名保持一致
renderScene(router, navigator) {
console.log("renderScene");
Navigator.navigator = navigator;
switch (router.name) {
case "register": // 当声明路径为register 加载 RegisterLeaf模块
return < RegisterLeaf navigator={navigator}/>;
case "waiting": //当声明路径为Waiting 加载 Waiting模块
console.log("waiting");
return < WaitingLeaf phoneNumber={router.phoneNumber}
userPW={router.userPW}
navigator={navigator}/>
}
} // 挂载的时候调用
componentDidMount() {
console.log("componentDidMount");
//监听Android 返回键按下时,判断导航的路径长度是否大于1 大于1 表示当前视图下最少还有一个视图
BackAndroid.addEventListener('hardwareBackPress',this.handleBack);
}
handleBack(){
const navigator = Navigator.navigator;
console.log(navigator);
if (navigator && navigator.getCurrentRoutes().length > 1) {
navigator.pop(); // 返回上一个视图
return true; // 返回true 表示已经处理了事件
}
return false;
}
// 移除的时候调用
componentWillUnMount() {
console.log("componentWillUnMount");
//清除组件被挂载接时设置的后退事件监听器
BackAndroid.removeEventListener('hardwareBackPress',this.handleBack); } render() {
return (
<Navigator
initialRoute={{name:'register'}}
configureScene={this.configureScene}
renderScene={this.renderScene}/>
);
}
} // 注册了 NaviModule 组件
AppRegistry.registerComponent('AwesomeProject', () => NaviModule);

Navigator组件中configureScene函数的用途是告知Navigator模块我们希望在视图转换时使用何种效果。

renderScene函数用来告知Navigator模块我们希望如何挂接当前的视图.

componentDidMount和 componentWillUnmount函数是React框架的两个生命周期的函数,NaviModule组件实现了这两个函数后,当这个组件被挂接到当前页面或者被移除时,这两个函数会被调用.

绘制原理

当navigator的push函数(或者replace函数,区别见代码注释) 被调用后,通过React Native的Navigator组件的工作机制,NaviModule的renderScene函数将被调用,并且push函数传入的变量成为renderScene函数的第一个参数.

当name等于 waiting时, 将WaitingLeaf模块挂接上去. 当name等于register时, RegisterLeaf模块被挂载上去.

属性总结

本节对属性做一个总结, 属性用于React Native组件外界向组件内传递变量或者数据.通过this.props属性来访问. 当属性的取值在组件外界被改变时,如果属性被组件中的UI以某种方式显示出来,则显示也会相应的发生改变. 在React Native组件内部,我们不可用对属性进行赋值操作,这种做法会导致运行时出错.

参考文章:

新手理解Navigator的教程

ReactNative的Navigator组件使用方式

React Native–导航

更多精彩请关注微信公众账号likeDev,公众账号名称:爱上Android。

从零学React Native之03页面导航的更多相关文章

  1. 从零学React Native之13 持久化存储

    数据持久化就是指应用程序将某些数据存储在手机存储空间中. 借助native存储 这种方式不言而喻,就是把内容传递给native层,通过原生API存储,详见从零学React Native之05混合开发 ...

  2. 从零学React Native之11 TextInput

    TextInput 组件是用来通过键盘输入文字,可以使用View组件和Text组件样式,没有自己特定的样式. 与Text组件类似,TextInput组件内部的元素不再使用FlexBox布局,而采用文本 ...

  3. 从零学React Native之02状态机

    本篇文章首发于简书 欢迎关注 之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 本篇文章主要介绍下下面的知识: 1.简单界面的搭 ...

  4. 从零学React Native之06flexbox布局

    前面我们接触了好多React Native代码, 并没有介绍RN中的组件具体是如何布局的,这一篇文章,重点介绍下flexbox布局. 什么是flexbox布局 React中引入了flexbox概念,f ...

  5. 从零学React Native之01创建第一个程序

    本篇首发于简书 欢迎关注 上一篇文章是时候了解React Native了介绍了React Native.大家应该对React Native有个初步的认识. 接下来我们就可以初始化一个React Nat ...

  6. 从零学React Native之04自定义对话框

    本篇主要介绍: 1. 自定义组件 2. Alert 对话框 自定义对话框 之前的我都是利用React Native提供的基础组件对它们进行排列组合, 其实自定义也很简单, 我们还是拿上一篇文章的例子进 ...

  7. 从零学React Native之14 网络请求

    通过HTTP或者HTTPS协议与网络侧服务器交换数据是移动应用中常见的通信方式. node-fetch是RN推荐的请求方式. React Native框架在初始化项目时, 引入了node-fetch包 ...

  8. 从零学React Native之12 组件的生命周期

    一个React Native组件从它被加载,到最终被卸载会经历一个完整的生命周期.所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命周期,是合理开发的关键. ES6语法和之前的ES5 ...

  9. 从零学React Native之10Text

    在React Native开发中,所有需要显示的字符串文本都需要放置在Text或者Text的子组件中.虽然在之前的文章中多次使用了Text组件,但是Text组件还是值得专门学习的, 并没有想象中的那么 ...

随机推荐

  1. windows device recovery tool 刷机

    ch 春节期间,拿出来诺基亚1020拍照,误删软件,无法登陆微软账号,考虑刷机处理 下载windows device recovery tool,进行刷机,但是固件下载一直失败 考虑下载好固件包,ff ...

  2. Linux 基础命令3 shell

    echo 显示一行文本 各种展开的实例 波浪线展开 算术表达式展开 支持的运算 奇怪的花括号展开 花括号的..用法 花括号(任选一个)的嵌套 参数展开$符很重要哦(一种展开做另一种的参数) 命令的替换 ...

  3. python实例 输出字符串和数字

    但有趣的是,在javascript里我们会理想当然的将字符串和数字连接,因为是动态语言嘛.但在Python里有点诡异,如下: #! /usr/bin/python a=2 b="test&q ...

  4. 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储。

    https://github.com/kcloze/swoole-jobs 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储.参考资料:swoole https:/ ...

  5. TP5.1 分页CSS样式(转载)

    效果如图: 1.在extend\目录下创建page目录,在page目录中创建Page.php文件,将以下代码放入文件中 <?php namespace page; use think\Pagin ...

  6. Django项目:CRM(客户关系管理系统)--10--04PerfectCRM实现King_admin注册功能02

    from django import conf #配置文件print("dj conf:",conf) #配置文件print("dj conf:",conf.s ...

  7. Faster RCNN算法demo代码解析

    一. Faster-RCNN代码解释 先看看代码结构: Data: This directory holds (after you download them): Caffe models pre-t ...

  8. 机器学习中的那些树——决策树(三、CART 树)

    前言 距上篇文章已经过了9个月 orz..趁着期末复习,把博客补一补.. 在前面的文章中介绍了决策树的 ID3,C4.5 算法.我们知道了 ID3 算法是基于各节点的信息增益的大小 \(\operat ...

  9. Sql server定时执行某个sql 通过Windows 计划任务(非代理Job方式)

    建立 bat文件.内容如下: osql -s "xxx.xxx.xx.x" -U sa -P sa -d DB -i TruncateSql.sql osql -S "l ...

  10. AOP Aspect 统一日志、异常处理、数据格式 【转】

    package com.gsww.chis.aop; import java.util.Arrays; import com.google.common.base.Throwables; import ...