React Native之 Navigator与NavigatorIOS使用
前言
学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习
本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所偏差,在学习中如果有错会及时修改内容,也欢迎万能的朋友们批评指出,谢谢
文章第一版出自简书,如果出现图片或页面显示问题,烦请转至 简书 查看 也希望喜欢的朋友可以点赞,谢谢
Navigator 与 NavigatorIOS 介绍
开发中,几乎所有的APP中或多或少都会涉及到多个界面间的切换,在React Native中有两个组件负责实现这样的效果 —— Navigator 和 NavigatorIOS
Navigator可以在iOS和Android同时使用,而NavigatorIOS则是包装了UIKit库的导航功能,使用户可以使用左划功能来返回到上一界面
Navigator 属性
官方文档中是这样解释的:使用导航器可以让你在应用的不同场景(页面)间进行切换。导航器通过路由对象来分辨不同的场景。利用renderScene方法,导航栏可以根据指定的路由来渲染场景
可以通过configureScene属性获取指定路由对象的配置信息,从而改变场景的动画或者手势。查看Navigator.SceneConfigs来获取默认的动画和更多的场景配置选项
configureScene:可选的函数,用来配置场景动画和手势。会带有两个参数调用(一个是当前的路由,一个是当前的路由栈)然后它会返回一个场景配置对象
- Navigator.SceneConfigs.PushFromRight(默认)
(route, routeStack) => Navigator.SceneConfigs.FloatFromRight效果:

- Navigator.SceneConfigs.FloatFromLeft
(route, routeStack) => Navigator.SceneConfigs.FloatFromLeft效果:

- Navigator.SceneConfigs.FloatFromBottom
(route, routeStack) => Navigator.SceneConfigs.FloatFromBottom效果:

- Navigator.SceneConfigs.FloatFromBottomAndroid
(route, routeStack) => Navigator.SceneConfigs.FloatFromBottomAndroid效果:

- Navigator.SceneConfigs.FadeAndroid
(route, routeStack) => Navigator.SceneConfigs.FadeAndroid效果:

- Navigator.SceneConfigs.HorizontalSwipeJump
(route, routeStack) => Navigator.SceneConfigs.HorizontalSwipeJump效果:

- Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
(route, routeStack) => Navigator.SceneConfigs.HorizontalSwipeJumpFromRight效果:

- Navigator.SceneConfigs.VerticalUpSwipeJump
(route, routeStack) => Navigator.SceneConfigs.VerticalUpSwipeJump效果:

- Navigator.SceneConfigs.VerticalDownSwipeJump
(route, routeStack) => Navigator.SceneConfigs.VerticalDownSwipeJump效果:

initialRoute:定义启动时加载的路由。路由是导航栏用来识别渲染场景的一个对象。
initialRoute必须是initialRouteStack(路由栈)中的一个路由。initialRoute默认为initialRouteStack中最后一项initialRouteStack:提供一个路由集合用来初始化。如果没有设置初始路由的话则必须设置该属性。如果没有提供该属性,它将被默认设置成一个只含有
initialRoute的数组naviagtionBar:可选参数,提供一个在场景切换的时候保持的导航栏
navigator:可选参数,提供从父导航器获得的导航器对象
onDidFocus:每当导航切换完成或初始化之后,调用此回调,参数为新场景的路由
onWillFocus:会在导航切换之前调用,参数为目标路由器
renderScene:必要参数,用来渲染指定路由的场景。调用的参数是路由和导航器
(route, navigator) => <MySceneComponent title={route.title} navigator={navigator} />sceneStyle:将会应用在每个场景的容器上的样式
Navigator 方法
- 如果你得到一个
navigator对象的引用,则可以调用许多方法来进行导航- getCurrentRoutes():获取当前栈里的路由,也就是push进来,没有pop掉的那些
- jumpBack():跳回之前的路由,当前前提是保留现在的,还可以再跳回来,会给你保留原样
- jumpForward():上一个方法不是盗用之前的路由,用这个就可以跳回来了
- push(route):跳转到新场景,并且将场景入栈,你可以稍后跳转过去
- pop():跳转回去并且卸载掉当前场景
- replace(route):用一个新的路由替换掉当前场景
- replaceAtIndex(route, index):替换掉指定序列的路由场景
- replacePrevious(route):替换掉之前的场景
- resetTO(route):跳转到新场景,并且重置整个路由栈
- immediatelyResetRouteStack(routeStack):用新的路由数组来重置路由栈
- popToRoute(route):pop到路由指定的场景,在整个路由栈中,处于指定场景之后的场景将会被卸载
- popToTop():pop到栈中的第一个场景,卸载掉所有的其它场景
Navigator 使用
这边我们先来完成一个最基本的导航控制器,然后慢慢深入,做一个完整的导航控制器
首先,我们先创建2个组件(home、Temp)并初始化组件,以供使用
- home组件代码
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native'; var Home = React.createClass( {
render() {
return (
<View style={styles.container}>
<Text>点击跳转</Text>
</View>
);
}
}); var styles = StyleSheet.create({
container: {
backgroundColor:'yellow',
flex:1,
justifyContent:'center',
alignItems:'center'
},
}); module.exports = Home;- temp组件代码
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native'; var Temp = React.createClass( {
render() {
return (
<View style={styles.container}>
<Text>点击返回</Text>
</View>
);
}
}); var styles = StyleSheet.create({
container: {
backgroundColor:'yellow',
flex:1,
justifyContent:'center',
alignItems:'center'
},
}); module.exports = Temp;实例化
Navigator需要2个必要的属性 —— initialRoute 和 renderSence,它们的作用分别是告诉导航器需要渲染的场景、根据路由描述渲染出来<Navigator
style={{flex: 1}} // 布局
initialRoute={{
name:'Home', // 名称
component:Home // 要跳转的板块
}} renderScene={(route, navigator) => { // 将板块生成具体的组件
let Component = route.component; // 获取路由内的板块
return <Component {...route.params} navigator={navigator} /> // 根据板块生成具体组件
}}
/>实际上这样我们的导航器就已经创建完毕了,但是从界面上我们看不到导航栏,但是已经具备导航功能,我们分别进到
home和temp文件中修改代码,看看是否真的已经实现导航功能- home代码
// 引入外部文件
var Temp = require('./Temp'); var Home = React.createClass( {
render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => {this.props.navigator.push({
component:Temp
})}}
>
<Text>点击跳转</Text>
</TouchableOpacity>
</View>
);
}
});- temp代码
var Temp = React.createClass( {
render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => {this.props.navigator.pop()}}
>
<Text>临时页面</Text>
</TouchableOpacity>
</View>
);
}
});效果:

在这里,我们还可以为导航器设置转场动画,以满足我们开发需求,官方已经提供了几种常用的转场动画,这边我们就取其中一种作示例,其它的效果可以参考上面的案例
<Navigator
initialRoute={{
name:'Home', // 名称
component:Home // 要跳转的板块
}} configureScene={(route) => { // 跳转动画
return Navigator.SceneConfigs.FloatFromBottom;
}} style={{flex: 1}}
renderScene={(route, navigator) => { // 将板块生成具体的组件
let Component = route.component; // 获取路由内的板块
return <Component {...route.params} navigator={navigator} /> // 根据板块生成具体组件
}}
/>效果:

为了让导航栏更加人性化,我们可以自己定制导航栏的样式,定制方式和我们自定义界面一样,只不过将按钮的响应改为导航栏对应的功能即可,这边就以最基本的导航栏样式为例
- 视图部分
var Home = React.createClass( {
render() {
return (
<View style={styles.container}>
{/* 实例化导航栏 */}
{this.setupNavBar()}
</View>
);
}, setupNavBar(){
return(
<View style={styles.navBarStyle}>
{/* 左边按钮 */}
<TouchableOpacity
onPress={() => {this.props.navigator.push({
component:Temp
})}}
>
<Text style={styles.leftButtonTitleStyle}>按钮</Text>
</TouchableOpacity> {/* 中间标题 */}
<Text style={styles.navBarTitleStyle}>标题</Text> {/* 右边按钮 */}
<TouchableOpacity>
<Text style={styles.rightButtonTitleStyle}>按钮</Text>
</TouchableOpacity>
</View>
)
}
});- 样式部分
var styles = StyleSheet.create({
container: {
backgroundColor:'yellow',
flex:1
}, navBarStyle: {
// 尺寸
width:width,
// 当前系统为iOS时,导航栏高度为64
height:Platform.OS === 'ios' ? 64 : 44,
// 背景颜色
backgroundColor:'rgba(255, 255, 255, 0.9)',
// 底部分隔线
borderBottomWidth:0.5,
borderBottomColor:'gray',
// 主轴方向
flexDirection:'row',
// 对齐方式
alignItems:'center',
justifyContent:'space-between',
// 当前系统为iOS时,下次移动15
paddingTop:Platform.OS === 'ios' ? 15 : 0
}, leftButtonTitleStyle: {
// 字体大小
fontSize:15,
// 字体颜色
color:'blue',
// 内边距
paddingLeft:8
}, navBarTitleStyle: {
// 字体大小
fontSize:17,
// 字体颜色
color:'black'
}, rightButtonTitleStyle: {
// 字体大小
fontSize:15,
// 字体颜色
color:'blue',
// 内边距
paddingRight:8
}
});iOS运行效果:

Android运行效果:

NavigatorIOS 属性
barTintColor:导航条的背景颜色
barTintColor='red' // 导航栏背景颜色效果:

initialRoute( {component: function, title: string, passProps: object, backButtonIcon: Image.propTypes.source, backButtonTitle: string, leftButtonIcon: Image.propTypes.source, leftButtonTitle: string, onLeftButtonPress: function, rightButtonIcon: Image.propTypes.source, rightButtonTitle: string, onRightButtonPress: function, wrapperStyle: [object Object]} ): 使用“路由”对象来包含要渲染的子视图、它们的属性、已经导航条配置。“push”和任何其他的导航函数的参数都是这样的路由对象(下面实例模块会详细讲解)
itemWrapperStyle:导航器中的组件的默认属性。一个常见的用途是设置所有页面的背景颜色
navigationBarHidden:布尔值,决定导航栏是否隐藏
navigationBarHidden={true} // 隐藏导航栏效果:

shadowHidden:布尔值,决定是否要隐藏1像素的阴影
shadowHidden={true} // 隐藏导航栏下面的阴影效果:

tintColor:导航栏上按钮的颜色
tintColor='orange' // 按钮的颜色效果:

titleTextColor:导航器标题的文字颜色
titleTextColor='green' // 导航栏标题的文字颜色效果:

translucent:布尔值,决定导航条是否半透明(注:当不半透明时页面会向下移动导航栏等高的距离,以防止内容被遮盖)
translucent={false} // 决定导航栏是否半透明(注:当不半透明时页面会向下移动导航栏等高的距离,以防止内容被遮盖)效果:

interactivePopGestureEnabled:决定是否启用滑动返回手势。不指定此属性时,手势会根据
navigationBar的显隐情况决定是否启用(显示时启用手势,隐藏时禁用手势),指定此属性后,手势与navigationBar的显隐情况无关interactivePopGestureEnabled={false} // 决定是否启用滑动返回手势效果:

NavigatorIOS 方法
push(route):导航器跳转到一个新的路由
pop():回到上一页
popN():回到N页之前。当 N=1 的时候,效果和 pop() 一样
replace(route):替换当前页的路由,并立即加载新路由的视图
replacePrevious(route):替换上一页的路由/视图
replacePreviousAndPop(route):替换上一页的路由/视图并且立即切换回上一页
resetTO(route):替换最顶级的路由并且回到它
replaceAtIndex:替换指定路由
popToRoute(route):一直回到某个指定的路由
popToTop():回到最顶层的路由
NavigatorIOS 使用
先来看看怎么使用
NavigatorIOS,我们需要给他指定一个路由,这样它才能知道显示哪个页面和
Navigator一样NavigatorIOS需要有个根视图来完成初始化,所以我们需要先创建一个组件来描述这个界面,并将这个组件通过路由的形式告诉NavigatorIOS,这样就可以将这个界面展示出来首先,创建一个
Home组件,用来作为NavigatorIOS的根视图- 视图部分
var Home = React.createClass( {
render() {
return (
<View style={styles.container}>
<Text>点击跳转页面</Text>
</View>
);
}
});- 样式部分
var styles = StyleSheet.create({
container: {
// 背景颜色
backgroundColor:'yellow',
flex:1,
// 对齐方式
justifyContent:'center',
alignItems:'center'
},
});接着我们在
index.ios.js内获得Home文件
// 引用外部文件
var Home = require('./home');- 然后我们实例化一个
NavigatorIOS并设置路由
var navigatorDemo = React.createClass( {
render() {
return (
<NavigatorIOS
initialRoute={{
component: Home, // 要跳转的页面
title:'首页' // 跳转页面导航栏标题
}}
style={{flex:1}} // 此项不设置,创建的导航控制器只能看见导航条而看不到界面
/>
);
}
});效果:

这样我们就完成了基本的导航控制器了,那么怎么进行跳转呢?其实也很简单,官方提供的方法内有多种供我们选择(具体参考上面的方法一栏)
- 这边我们就来实现最简单的跳转和返回,我们使用
TouchableOpacity让Home中的 标签 拥有接收事件的能力,并且当点击的时候通过调用props来获取 navigator,并传递给他一个路由,使其知道跳转到哪个页面
var Home = React.createClass( {
render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => {this.props.navigator.push({
component:Temp, // 需要跳转的页面
title:'跳转的界面' // 跳转页面导航栏标题
})}}
>
<Text>点击跳转页面</Text>
</TouchableOpacity>
</View>
);
}
});效果:

- 这边我们就来实现最简单的跳转和返回,我们使用
这边顺便来看下导航栏左右两边的按钮怎么设置,并且响应点击事件
initialRoute={{
component: Home, // 要跳转的页面
title:'首页', // 跳转页面导航栏标题
leftButtonTitle:'左边', // 实例化左边按钮
onLeftButtonPress:() => {alert('左边')}, // 左边按钮点击事件
rightButtonTitle:'右边', // 实例化右边按钮
onRightButtonPress:() => {alert('右边')} // 右边按钮点击事件
}}效果:

当然图片设置的方式也是一样的,只需要调用
leftButtonIcon和 'rightButtonIcon` 即可(和TabBarIOS一样,只支持本地图片)
补充
- props:组件中的props是一种父级向子级传递数据的方式
- this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是
this.props.children属性。它表示组件的所有子节点 - 它里面包含了所有的属性,所以上面我们在别的文件中可以通过
this.props.navigator的方式获取navigator
- this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是
- state:
state是React中组件的一个对象.React把用户界面当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界面与数据保持一致。React中,更新组件的state,会导致重新渲染用户界面(不要操作DOM).简单来说,就是用户界面会随着state变化而变化- 原理:常用的通知React数据变化的方法是调用
setState(data,callback).这个方法会合并data到this.state,并重新渲染组件.渲染完成后,调用可选的。callback回调.大部分情况不需要提供callback,因为React会负责吧界面更新到最新状态 - 哪些组件应该有 state
- 大部分组件的工作应该是从
props里取数据并渲染出来.但是,有时需要对用户输入,服务器请求或者时间变化等作出响应,这时才需要state - 组件应该尽可能的无状态化,这样能隔离state,把它放到最合理的地方(Redux做的就是这个事情?),也能减少冗余并易于解释程序运作过程
- 常用的模式就是创建多个只负责渲染数据的无状态(stateless)组件,在他们的上层创建一个有状态(stateful)组件并把它的状态通过props
- 传给子级.有状态的组件封装了所有的用户交互逻辑,而这些无状态组件只负责声明式地渲染数据
- 大部分组件的工作应该是从
- 哪些应该作为 state
state应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据.这中数据一般很小且能被JSON序列化.当创建一个状态化的组件的时候,应该保持数据的精简,然后存入this.state。 在render()中在根据state来计算需要的其他数据.因为如果在state里添加冗余数据或计算所得数据,经常需要手动保持数据同步
- 哪些不应该作为 state
this.state应该仅包括能表示用户界面状态所需要的最少数据.因此,不应该包括:- 计算所得数据:
- React组件:在render()里使用props和state来创建它
- 基于props的重复数据:尽可能保持用props来做作为唯一的数据来源.把props保存到state中的有效的场景是需要知道它以前的值得时候,因为未来的props可能会变化
- 计算所得数据:
- 原理:常用的通知React数据变化的方法是调用
React Native之 Navigator与NavigatorIOS使用的更多相关文章
- React Native导航器Navigator
React Native导航器Navigator 使用导航器可以让你在应用的不同场景(页面)间进行切换.导航器通过路由对象来分辨不同的场景.利用renderScene方法,导航栏可以根据指定的路由来渲 ...
- [React Native] Basic iOS Routing -- NavigatorIOS
Inside the app component, we use NavigatiorIOS to render the compoent: class githubnotetaker extends ...
- React Native之Navigator
移动应用很少只包含一个页面.从你添加第二个页面开始,就得考虑如何管理多个页面间的跳转了. 导航器正是为此而生.它可以管理多个页面间的跳转,也包含了一些常见的过渡动画,包括水平翻页.垂直弹出等等. Na ...
- react native 导航器 Navigator 简单的例子
最近学习react native 是在为全栈工程师而努力,看网上把react native说的各种好,忍不住学习了一把.总体感觉还可以,特别是可以开发android和ios这点非常厉害,刚开始入门需要 ...
- react native进一步学习(NavigatorIOS 学习)
特别申明:本人代码不作为任何商业的用途,只是个人学习的一些心得,为了使得后来的更多的程序员少走一些弯路.*(如若侵犯你的版权还望见谅)*. 开发工具:WebStorm,xcode 1. rn的创建的时 ...
- react native的Navigator组件示例
import React, {Component} from 'react';import {ScrollView, StyleSheet, Text, View, PixelRatio} from ...
- React Native使用Navigator组件进行页面导航报this.props....is not a function错误
在push的时候定义回调函数: this.props.navigator.push({ component: nextVC, title: titleName, passProps: { //回调 g ...
- React Native中Navigator的安装与使用
一.安装Navigator 1.安装react-native-deprecated-custom-components npm install react-native-deprecated-cust ...
- React Native APP结构探索
APP结构探索 我在Github上找到了一个有登陆界面,能从网上获取新闻信息的开源APP,想来研究一下APP的结构. 附上原网址:我的第一个React Native App 具体来讲,就是研究一个复杂 ...
随机推荐
- Goodbye2014,Hello2015
正如我在研发会议上说的,总结是为了更好的计划:而计划,则是让你做事有目标,有方向:有了目标和方向,你才能真正把事情做成! 总的来说2014年可以归纳为下图: 2014年总结 一年的活动,基本可以归纳为 ...
- Linux Nano命令
Nano命令指南 今天在输命令时,无意中输入了nano,对这个命令不太熟悉,结果不知道如何才能退出,保存,赶快查了一下资料,原来是这样的啊. 打开文件与新建文件 使用nano打开或新建文件,只需键入: ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(20)-权限管理系统-根据权限获取菜单
系列目录 不知不觉到20讲,真是漫长的日子,可惜最近工作挺忙,要不可以有更多的时间来更新,多谢大家的一路支持.如果你觉得好,记得帮我点击推荐^-^ 我们在之前已经插入一些真实数据,其中包含了一个用户和 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出
系列目录 昨天文章太过仓促没有补充导出的示例源码,在者当时弄到到很晚没时间做出导出功能,对阅读理解造成影响,现补充一份示例源码,顺便补充导出的功能说明,望理解 示例代码下载 https://yun ...
- 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库
昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所 ...
- Core Java 总结(数据类型,表达式问题)
2016-10-18 整理 写一个程序判断整数的奇偶 public static boolean isOdd(int i){ return i % 2 == 1; } 百度百科定义:奇数(英文:odd ...
- Linux驱动开发—— of_property_read_u8
在使用設備樹的時候, 有時會遇到下面的問題. 在設備樹中配置的屬性如下: fusb301,init-mode = <0x20>; 但是在驅動中讀出的卻是: rc = of_property ...
- 你真的会玩SQL吗?你所不知道的 数据聚合
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 2.ASP.NET MVC 中使用Crystal Report水晶报表
上一篇,介绍了怎么导出Excel文件,这篇文章介绍在ASP.NET MVC中使用水晶报表. 项目源码下载:https://github.com/caofangsheng93/CrystalReport ...
- IL接口和类的属性
上一篇文章学习了IL的入门,接下来我们再通过两个例子来了解下类的属性.构造函数以及接口的使用 一.类的属性.构造函数 1.先看下我们要构建的类的C#代码,然后再进行IL的实现,示例代码如下: [Ser ...





















