ReactNative: 使用导航栏组件-NavigatorIOS组件和Navigator组件
一、简言
在软件开发中,不论是Web还是App,它们的应用程序都是由很多的功能视图组成的。对于这些组合的视图,如何实现页面间平滑地过渡,应用都有统一的一套跳转机制,这个功能就是路由或者叫导航。应用程序通过导航,可以自由地实现页面之间的切换、前进和后退。在React中使用的是React Router,在iOS中使用的是UIKit的导航视图UINavigation和导航控制器。而在React-Native中,也提供了专门切换视图的导航栏组件NavigatorIOS和Navigator,这两个是兄弟组件,功能基本相同,区别在于封装性高低。NavigatorIOS组件的封装程度更高提供了基础的API和属性,开发者可以很方便的定制一个功能丰富的导航栏,而Navigator组件相比较而言比较简陋,它提供了足够的空间让开发者去定制,对于复杂的导航栏,它定制能力更高,而且可跨平台使用。其实,NavigatorIOS组件本质上是对UIKit的UINavigation的包装,使用NavigatorIOS组件进行页面的切换实质上就是调用了UIKit原生导航功能。本文将一一研究。
二、navigator对象
在组件视图进行切换的时候,navigator会作为一个属性对象被传递。我们可以通过this.props.navigator获取navigator对象。掌握navigator对象是使用NavigatorIOS组件和Navigator组件的前提基础,因为它可以控制器路由的跳转和组件的加载。navigator对象的主要API如下:
//加载一个新的页面或者视图或者路由,并跳转到该页面
push(route) //返回到上一个页面
pop() //一次性返回N个页面,也即返回到指定页面,当N=1,与pop()相同
popN(n) //替换当前的路由
replace(route) //替换前一个页面的视图并且回退过去
replacePrevious(route) //取代最顶层的路由并且回退回去
resetTo(route) //回到最顶层视图
popToTop()
三、NavigatorIOS组件
1、路由initialRoute默认是一个JS对象,代表一个页面或者视图,NavigatorIOS组件默认路由提供了initialRoute属性,如下所示:
import React, { Component } from 'react';
import {
NavigatorIOS
} from 'react-native'; export default class NavigatorBar extends Component{ render(){
return (
<NavigatorIOS
initialRoute={{
component: MyComponent,
title: "MyComponent Title",
passProps: {myProp:"XYQ"}
}}
/>
);
}
} //component : 表示当前页面需要加载的组件视图
//title: 表示需要显示的标题
//passProps:表示用于页面间传递数据
2、NavigatorIOS组件属性有两大部分,分别是自身属性和持有的路由的属性,如下所示:
自身属性:
//导航条的背景颜色
barTintColor //初始化路由,它是一个JavaScript对象
initialRoute //每一页定制样式,可以设置每一个页面的背景颜色
itemWrapperStyle //是否隐藏导航栏
navigationBarHidden //是否隐藏阴影
shadowHidden //导航栏上按钮的颜色设置
tintColor //导航栏上字体的颜色
titleTextColor //导航栏是否半透明
translucent
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 //包裹样式
warpperStyle: [Object Object]
四、Navigator组件
1、注意事项:如果RN版本升级到0.43以上的话,Navigator已过期,不能直接从react-native里面获取了,而是作为一个单独的库模块,解决方案如下:
//安装
npm install react-native-deprecated-custom-components --save //已过期失效,推荐使用第二个命令进行安装
yarn add react-native-deprecated-custom-components //可使用 //导入
import {Navigator} from 'react-native-deprecated-custom-components'
2、Navigator组件提供的属性如下:
/**
* 配置跳转动画
* (route, routeStack) => Navigator.SceneConfigs.FloatFromRight
*/
configureScene: PropTypes.func, /**
* 渲染场景
* (route, navigator) =>
* <MySceneComponent title={route.title} navigator={navigator} />
*/
renderScene: PropTypes.func.isRequired, /**
* 配置路由
*/
initialRoute: PropTypes.object,
initialRouteStack: PropTypes.arrayOf(PropTypes.object), /**
* 路由即将跳转时调用
*/
onWillFocus: PropTypes.func, /**
* 路由完成跳转时调用
*/
onDidFocus: PropTypes.func, /**
* 导航栏
*/
navigationBar: PropTypes.node, /**
* navigator对象
*/
navigator: PropTypes.object, /**
* 场景样式
*/
sceneStyle: ViewPropTypes.style,
3、虽然Navigator组件很粗糙,但是它的定制性极强,可以
很好解决NavigatorIOS组件不能跨平台和自定义的问题。Navigator组件只提供跳转功能,界面需要开发者自己去定制。使用步骤大致如下:
//1、配置路由
initialRoute={{component:this.props.component, passProps:{}}} //2、配置跳转
configureScene={()=>{return Navigator.SceneConfigs.FloatFromBottom;}} //3、渲染场景
renderScene={(route, navigator) => {
// ...扩展符, 作用:如果是对象,就获取对象中所有值,如果是数组,就获取数组中所有值
const Component = route.component;
return (
<View style={{flex:}}> //使用flex设置导航尺寸
<Component navigator={navigator} route={route} {... route.passProps}>
</View>
)
}
4、Navigator组件支持的跳转方向和类型有很多,如下所示:
Navigator.SceneConfigs.PushFromRight //(默认)
Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.FloatFromLeft
Navigator.SceneConfigs.FloatFromBottom
Navigator.SceneConfigs.FloatFromBottomAndroid
Navigator.SceneConfigs.FadeAndroid
Navigator.SceneConfigs.HorizontalSwipeJump
Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
Navigator.SceneConfigs.VerticalUpSwipeJump
Navigator.SceneConfigs.VerticalDownSwipeJump
5、导航过渡过程中,可以配置的回调函数如下:
//每当导航切换完成或初始化之后,调用此回调,参数为新场景的路由
onDidFocus function //会在导航切换之前调用,参数为目标路由
onWillFocus function
五、使用NavigatorIOS组件
需求:新闻列表页跳转到新闻详情页。
index.ios.js程序入口文件
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/ import React, { Component } from 'react';
import NavigatorBar from './src/NavigatorBar' import {
AppRegistry,
View
} from 'react-native'; export default class ReactNativeDemo extends Component { render() {
return (
<NavigatorBar/>
);
}
} AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
Navigator.js创建的NavigatorIOS导航栏组件文件
import React, { Component } from 'react';
import NewsHome from './NewsHome' import {
NavigatorIOS
} from 'react-native'; export default class NavigatorBar extends Component{ render(){
return (
<NavigatorIOS
style={{flex: }} //设置导航栏样式
barTintColor={'purple'} //设置导航栏颜色
titleTextColor={'white'} //设置导航标题颜色
itemWrapperStyle={{backgroundColor:'orange'}} //设置导航页面背景颜色
initialRoute={{
component: NewsHome, //设置路由,列表主页
title: "新闻列表", //设置导航标题
passProps: {} //传递数据
}}
/>
);
}
}
NewsHome.js新闻列表页文件
import React, { Component } from 'react';
import List from './List' import {
View,
StyleSheet
} from 'react-native'; /*
* 此处使用扩展运算符...this.props,将属性navigator传递到List组件中,因为List组件中无法直接获取navigator组件对象
* */
export default class NewsHome extends Component{
render() {
return (
<View style={styles.container}>
<List title="1、多地校长、专家在京探讨全息教育" {...this.props}/>
<List title="2、中国网络安全产业高峰论坛在京召开" {...this.props}/>
<List title="3、启动四天多 北京冬奥赛会志愿者报名人数超46万" {...this.props}/>
<List title="4、丰台消防救援支队筑牢辖区冬季火灾防线" {...this.props}/>
</View>
);
}
} const styles = StyleSheet.create({
container:{
marginTop: ,
backgroundColor:'white'
}
});
List.js新闻列表组件文件
import React, { Component } from 'react';
import NewDetail from "./NewsDetail"; import {
StyleSheet,
View,
Text
} from 'react-native'; export default class List extends Component{ constructor(props){
super(props);
this.push = this.push.bind(this); //绑定push事件,绑定方式有多种,这是其中方法之一
} //跳转到详情页
push(){
let {navigator} = this.props; //作用域本地化
navigator.push({ //navigator对象调用push函数
component: NewDetail, //新闻详情页
title:"详情页", //设置新闻详情页导航标题
leftButtonTitle:"返回", //设置新闻详情页导航左边按钮
rightButtonTitle:"消息", //设置新闻详情页导航右边按钮
onLeftButtonPress:(() => navigator.pop()), //返回上一页:列表主页,navigator对象调用pop函数
onRightButtonPress:(() => alert("welcome to you")), //弹出吐司
wrapperStyle: {backgroundColor:'yellow'} //设置页面背景色
})
} render() {
return (
<View style={styles.list_item}>
<Text style={styles.list_font} onPress={this.push}>{this.props.title}</Text>
</View>
);
}
} const styles = StyleSheet.create({
list_item: {
height: ,
borderBottomWidth: ,
borderBottomColor: '#DDD',
justifyContent: 'center'
},
list_font: {
fontSize: ,
fontWeight: 'bold',
color: 'black'
}
});
NewsDetail.js新闻详情页文件
import React, { Component } from 'react'; import {
StyleSheet,
View
} from 'react-native'; export default class NewsDetail extends Component{
render() {
return (
<View style={styles.container}/>
)
}
} const styles = StyleSheet.create({
container:{
marginTop: ,
backgroundColor:'white'
}
});
模拟器运行结果如下:
六、使用Navigator组件
1、无导航栏,只使用路由功能:
inde.ios.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/ import React, { Component } from 'react';
import NavigatorCustomBar from './src/NavigatorCustomBar' import {
AppRegistry
} from 'react-native'; export default class ReactNativeDemo extends Component { render() {
return (
<NavigatorCustomBar/>
);
}
} AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
NavigatorCustomBar.js
import React, { Component } from 'react';
import { Navigator } from 'react-native-deprecated-custom-components'; import {
View,
Text,
StyleSheet
} from 'react-native'; /*
* 封装Navigator
* 所有的切换动画都是从底部往上,回退时从上往底部
* 这里通过{...passProps}模仿NavigatorIOS的passProps进行传值
* initialRoute中的component: 传递的入口组件
*
* */
export default class NavigatorCustomBar extends Component{ render(){
return (
<Navigator
style={{flex:}} //设置样式
initialRoute={{component:HomePage, passProps:{}}} //配置路由
configureScene={()=> {return Navigator.SceneConfigs.FloatFromBottom;}} //设置跳转动画
renderScene={(route, navigator) => { //渲染页面场景
const Component = route.component;
return (
<Component navigator={navigator} route={route} {...route.passProps}/>
)
}}
/>
)
}
} //首页
class HomePage extends Component{ render(){
return (
<View style={styles.home}>
<Text style={styles.font} onPress={()=>this.props.navigator.push({component: DetailPage})}>
HomePage
</Text>
</View>
);
}
} //详情页
class DetailPage extends Component{ render(){
return (
<View style={styles.detail}>
<Text style={styles.font} onPress={()=>this.props.navigator.pop()}>
DetailPage
</Text>
</View>
);
}
} //样式
const styles = StyleSheet.create({
home:{
flex: ,
backgroundColor:'red',
justifyContent: 'center',
alignItems:'center',
},
detail:{
flex: ,
backgroundColor:'green',
justifyContent: 'center',
alignItems:'center',
},
font:{
fontSize:,
color:'white'
}
});
2、有导航栏,且使用路由功能:
inde.ios.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/ import React, { Component } from 'react';
import NavigatorCustomBar from './src/NavigatorCustomBar' import {
AppRegistry
} from 'react-native'; export default class ReactNativeDemo extends Component { render() {
return (
<NavigatorCustomBar/>
);
}
} AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
NavigatorCustomBar.js
import React, { Component } from 'react';
import { Navigator } from 'react-native-deprecated-custom-components'; import {
View,
Text,
StyleSheet
} from 'react-native'; /*
* 封装Navigator
* 所有的切换动画采用默认方式
* 这里通过{...passProps}模仿NavigatorIOS的passProps进行传值
* initialRoute中的component: 传递的入口组件
* */
export default class NavigatorCustomBar extends Component{ //1、路由初始化
initialRoute = {
name:"HomePage", //路由名称
component:HomePage, //路由页面
index:, //页面索引
passProps:{leftTitle:"返回",midTitle:"首页",rightTitle:""} //透传数据
}; //2、动画初始化
configureScene = () => {
return Navigator.SceneConfigs.PushFromRight;
} //3、场景初始化
renderScene = (route, navigator) => {
const Component = route.component;
return <Component navigator={navigator} route={route} {...route.passProps}/>
} //4、Mapper初始化
navBarRouteMapper = {
//左边按钮
LeftButton(route, navigator, index){
if (index <= ) return;
return (
<Text style={styles.left} onPress={ () => navigator.pop()}>
{route.passProps.leftTitle}
</Text>
);
},
//中间标题
Title(route, navigator){
return (
<Text style={styles.mid}>
{route.passProps.midTitle}
</Text>
);
},
//右边按钮
RightButton(route, navigator){
if(!route.passProps.rightTitle) return;
return (
<Text style={styles.right} onPress={() => alert('welcome to me!')}>
{route.passProps.rightTitle}
</Text>
);
}
}; render(){
return (
<Navigator
style={{flex:}} //设置样式
initialRoute={this.initialRoute} //配置路由
configureScene={this.configureScene} //设置跳转动画
renderScene={this.renderScene} //渲染页面场景
navigationBar={ //设置导航栏Mapper
<Navigator.NavigationBar
style={styles.navContainer}
routeMapper={this.navBarRouteMapper}/>
}
/>
)
}
} //首页
class HomePage extends Component{ //设置详情页导航栏
pushToDetailPage(){
this.props.navigator.push({
index:,
component: DetailPage,
passProps:{
leftTitle: this.props.leftTitle,
midTitle:"详情",
rightTitle:"消息"
}
})
} render(){
return (
<View style={styles.home}>
<Text style={styles.font} onPress={this.pushToDetailPage.bind(this)}>
this is HomePage
</Text>
</View>
);
}
} //详情页
class DetailPage extends Component{ render(){
return (
<View style={styles.detail}>
<Text style={styles.font} onPress={()=>this.props.navigator.pop()}>
this is DetailPage
</Text>
</View>
);
}
} //样式
const styles = StyleSheet.create({
navContainer:{
height:,
backgroundColor:'#41ABF7'
},
left:{
paddingLeft:,
paddingTop:,
flex:/,
fontSize:,
color:'white'
},
mid:{
paddingTop:,
flex:/,
fontSize:,
color:'white'
},
right:{
paddingRight:,
paddingTop:,
flex:/,
fontSize:,
color:'white'
},
home:{
flex: ,
marginTop:,
backgroundColor:'orange',
justifyContent: 'center',
alignItems:'center',
},
detail:{
flex: ,
marginTop:,
backgroundColor:'brown',
justifyContent: 'center',
alignItems:'center',
},
font:{
fontSize:,
color:'white'
}
});
ReactNative: 使用导航栏组件-NavigatorIOS组件和Navigator组件的更多相关文章
- React-native 底部导航栏(二)
1.组件安装:npm install react-native-router-flux --save 2.定义菜单图片和文字: import React, { Component } from 're ...
- react-native底部导航栏实现
react-native-tab-navigator实现: bottom.js代码如下: import React, {Component} from 'react'; import {StyleSh ...
- 【React -- 9/100】 抽离顶部导航栏 - [组件复用]
今天写的页面中需要重复使用到顶部导航栏,所以把顶部导航栏抽离出来 考虑复用组件的健壮性,使用PropTypes校验,可以自定义一个click事件 JSX import React from " ...
- 微信小程序——导航栏组件
组件内属性详解 属性 类型 默认值 必填 说明 nav-postion String relative 否 导航栏(包含导航栏以及状态栏)的position,可取值relative.fixed.a ...
- React Native(四)——顶部以及底部导航栏实现方式
效果图: 一步一步慢慢来: 其实刚入手做app的时候,就应该做出简单的顶部以及底部导航栏.无奈又在忙其他事情,导致这些现在才整理出来. 1.顶部导航栏:react-native-scrollable- ...
- 前端Vue项目——初始化及导航栏
一.项目初始化 创建webpack模板项目如下所示: MacBook-Pro:PycharmProjects hqs$ vue init webpack luffy_project ? Project ...
- [RN] React Native 自定义导航栏随滚动渐变
React Native 自定义导航栏随滚动渐变 实现效果预览: 代码实现: 1.定义导航栏 NavPage.js import React, {Component} from 'react'; im ...
- SAP CRM 将组件整合至导航栏中
到现在,我们已经可以让组件独立地显示.我们只是运行它.让它显示在Web UI中.让我们把组件整合进导航栏,使我们可以在正常登录Web UI时访问它. 步骤一: 为你的UI组件主窗体创建一个内向插件. ...
- 初尝微信小程序2-Swiper组件、导航栏标题配置
swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...
随机推荐
- hbuilder/hbuilderx 无法检测到模拟器
常用模拟器的端口 夜神模拟器 端口号 :62001 海马玩模拟器 端口号:26944 网易mumu模拟器端口号:7555 天天模拟器 端口号:6555 AndroidStudio自带模拟器 端口号: ...
- .Net Core 3.0 以及其前版本编写自定义主机,以允许本机程式(转载)
像所有的托管代码一样,.NET Core 应用程序也由主机执行. 主机负责启动运行时(包括 JIT 和垃圾回收器等组件)和调用托管的入口点. 托管 .NET Core 运行时是高级方案,在大多数情况下 ...
- Hadoop相关问题解决
Hadoop相关问题解决 Hive 1.查询hivemeta信息,查到的numRows为-1 集群厂商 集群版本 是否高可用 是否开启认证 cdh 不限 不限 不限 在hivemeta库中可以通过以下 ...
- 面试必问:JVM类加载机制详细解析
前言 在Java面试中,简历上有写JVM(Java虚拟机)相关的东西,JVM的类加载机制基本是面试必问的知识点. 类的加载和卸载 JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是cla ...
- C语言每日一练——第1题
一.程序功能 程序的功能是:将大于整数m且紧靠m的k个素数存入数组xx.并把in.dat文件的内容输入到程序,并把输出结果输出道out.dat文件夹中例如:若输入17,5 则应该输入:19,23,29 ...
- 205K+程序员关注过的问题:为什么不应该使用Java的原始类型?
在逛 Stack Overflow 的时候,发现了一些访问量像熊耳山一样高的问题,比如说这个:为什么不应该使用Java的原始类型?访问量足足有 205K+,这不得了啊!说明有很多很多的程序员被这个问题 ...
- java8-从Lamda到方法引用和构造引用
一方法引用概述 经过前面2章Lamda原理引入和Lamda解析,基本就会熟练使用Lamda表达式,这次我们更深入点.来了解一下方法引用. 方法引用是特定Lamda表达式的一种简写,其思路就是能替换La ...
- 955 不加班的公司名单:955.WLB
前两天说到,韩老师的 Github 总 star 数量超过了 20000!全球排名第 232! 他,TypeScript GitHub Star 上海第一,全国第四!GitHub 总标星超两万! 其实 ...
- javaWeb实现验证码--代码超简单
1.前端显示 HTML: <h3>验证码:</h3> <input type="text" name="validationCode&quo ...
- deinit 没执行
写了一个自定义的UIView,其中包含代理 然后设置UIViewController为此UIView的代理 结果UIViewController里的deinit没执行,导致内存 ...