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 具体来讲,就是研究一个复杂 ...
随机推荐
- AutoMapper(四)
返回总目录 自定义值解析 虽然AutoMapper覆盖了相当一部分目标成员的映射场景,但是还有 1-5%的目标值需要解析处理一下.很多时候,自定义的值解析是可以放在领域层的领域逻辑.然而,如果该逻辑只 ...
- Linux3 在VMware中搭建CentOS6.5虚拟机
前言: 本文主要是我在大家hadoop集群之前 ,需啊先安装CentOS虚拟机,记录在此,作为参考.如果能帮助到其他人,自然是更好啦. =========================== ...
- web音乐播放器总结
前言 项目暂时告一段落,胸中有股炽热之气望喷涌而出!忍不住吐槽,为什么程序员要加班啊,为什么产品下达deadline,就得把这生死剑架在程序员的脖子上.卧槽,听说程序员在国外是叫工程师的.最近看了很多 ...
- 我对BFC的理解
最初这篇文章打算回答寒冬大神的第一问,谈谈CSS布局.本来呢我以为布局主要涉及float跟display相关属性,以及他们的包含框.静态位置等等.后来看了大神的一片面试文章,嗯?这里怎么还有个BFC, ...
- iOS开发系列--Swift 3.0
概述 从写第一篇Swift文章的时候到现在Swift已经从1.2发展到了今天的3.0,这期间由于Swift目前还在发展阶段并不能向下兼容,因此第一篇文章中的部分代码在当前的Xcode环境中已经无法运行 ...
- SQL Server 索引和表体系结构(聚集索引)
聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在各个网站上面也有很多关于这方面写的不错的文章,我写这篇文章的目的也是为了将所有的知识点尽可能的组 ...
- ASP.NET Web API 控制器创建过程(一)
ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...
- Restful WebApi项目开发实践
前言 踩过了一段时间的坑,现总结一下,与大家分享,愿与大家一起讨论. Restful WebApi特点 WebApi相较于Asp.Net MVC/WebForm开发的特点就是前后端完全分离,后端使用W ...
- ABP教程-给项目添加SwaggerUI,生成动态webapi
上一篇,我们是正式将ABP生成的代码项目,跑起来了,然后演示了下多租户的不同.那么这篇我们就来实现下SwaggerUI. Q:SwaggerUI是干什么的呢? A:他是一个能将我们的webapi,通过 ...
- 给 Android 研发的一些的建议
作为应用程序开发人员,我们需要注意在开发应用程序时的一些问题. 这些问题的安全级别是取决于应用程序的类型和使用域. 在这里列举了一些我们在开发中需要注意的一些问题: 开发日志输出相关: 1. 不要在 ...