React Native导航器之react-navigation使用
在上一节Navigation组件,我们使用系统提供的导航组件做了一个跳转的例子,不过其实战能力不强,这里推荐一个超牛逼的第三方库:react-navigation。在讲react-navigation之前,我们先看一下常用的导航组件。
导航控件
常见的导航主要分为三种:
1.StackNavigator :类似于普通的Navigator,屏幕上方导航栏
2.TabNavigator:obviously, 相当于iOS里面的TabBarController,屏幕下方标签栏
3.DrawerNavigator:抽屉效果,左侧滑出这种效果。
Navigation 使用
在你使用navigation的每一个界面navigation都提供相关的属性和响应方法,常见的有:
navigate 定义跳转到另一个页面
调用此方法去链接你的其他界面,主要有以下参数:
·routeName- 目标路由名称,将在你的app router中注册
·params-将参数合并到目标router中
·action-(高级)sub-action ,如果该界面是一个navigator的话,将运行这个sub-action
例如:
class HomeScreen extends React.Component {
render() {
const {navigate} = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() => navigate('Profile', {name: 'Brent'})}
title="点击我跳转"
/>
</View>
)
}
}
state当前路由状态
每个界面通过this.props.navigation.state去访问它的router,state其中包括了:
·routeName - router配置的名称
·key-用来区分router的唯一标示
·params-可选的一些string参数
setParams-更改router中的参数
该方法允许界面更改router中的参数,可以用来动态的更改header的内容
goBack-返回,pop回上一级
dispatch -使用dispatch可以向任何navigation传递一些其他的action,主要支持的action有
Navigate使用
例如:
import { NavigationActions } from 'react-navigation'
const navigationAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
// navigate can have a nested navigate action that will be run inside the child router
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigationAction)
Reset
Reset方法会擦除掉所有的导航状态,并且使用新的结果替代。
import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Profile'})
]
})
this.props.navigation.dispatch(resetAction)
SetParams
为指定的router更新参数,该参数必须是已经存在于router的param中。
import { NavigationActions } from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
params: {}, // these are the new params that will be merged into the existing route params
// The key of the route that should get the new params
key: 'screen-123',
})
this.props.navigation.dispatch(setParamsAction)
StackNavigator使用
StackNavigator使用比较简单,看一个常见的例子:
class MyHomeScreen extends React.Component {
static navigationOptions = {
title: 'Home', //设置navigator的title
}
render() {
return (
//button的onPress方法,实现点击跳转界面,并且传递参数name:Lucy
<Button
onPress={() => this.props.navigation.navigate('Profile', {name: 'Lucy'})}
title="Go to Lucy's profile"
/>
);
}
}
//生成路由关系
const ModalStack = StackNavigator({
Home: {
//对应界面MyHomeScreen
screen: MyHomeScreen,
},
Profile: {
path: 'people/:name',
screen: MyProfileScreen,
},
});
StackNavigatorConfig
option for the route(路由选项):
·initialRouteName -为stack设置默认的界面,必须和route configs里面的一个key匹配。
·initialRouteParams - 初始路由的参数。
·navigationOptions- 屏幕导航的默认选项。
·paths-route config里面路径设置的映射。
Visual Option(视觉选项):
·mode- 定义渲染(rendering)和转换(transitions)的模式,两种选项:
1) card-使用标准的iOS和Android的界面切换,这是默认的。
2)modal- 仅在iOS端有用,即模态出该视图。
·headerMode- 指定header应该如何被渲染,选项:
1)float- 共用一个header 意思就是有title文字渐变效果。
2)screen- 各用各的header 意思就是没有title文字渐变效果。
3)none- 没有header。
·cardStyle- 使用该属性继承或者重载一个在stack中的card的样式。
·onTransitionStart- 一个函数,在换场动画开始的时候被激活。
·onTransitionEnd- 一个函数,在换场动画结束的时候被激活。
Navigation Options
你还可以定义一个静态的navigationOptions在你的组件之上。
lass ProfileScreen extends React.Component {
//设置navigation选项
static navigationOptions = {
//标题
title: ({ state }) => `${state.params.name}'s Profile!`,
//头部定义了一个右按钮,来改变edit的状态 ing或者完成
header: ({ state, setParams }) => ({
// Render a button on the right side of the header
// When pressed switches the screen to edit mode.
right: (
<Button
title={state.params.editing ? 'Done' : 'Edit'}
onPress={() => setParams({editing: state.params.editing ? false : true})}
/>
),
}),
};
...
常用的配置中,主要有以下参数需要注意:
1)visible - bool值,header是否可见。
2)title-标题 String或者是一个react 节点
3)backTitle-返回按钮在iOS平台上,默认是title的值
4)right- react 节点显示在header右边,例如右按钮
5)left- react 节点显示在header左边,例如左按钮
6)style-header的style
7)titleStyle- header的title的style (^__^) 嘻嘻……
8)tintColor- header的前景色
·cardStack- 配置card stack
react-navigation
说完常见的导航器,我们在看看本文的重点:react-navigation的使用。
首先看一下效果:
1,在项目目录下,安装React-navigation库
npm install --save react-navigation
2,使用StactkNavigator来管理堆栈。暂且命名为HomeScreen.js。默认入口页面代码如下:
import React from 'react';
import {
AppRegistry,
Text,
} from 'react-native';
//导入stack导航组件
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',//标题
};
render() {
return <Text>Hello, Navigation!</Text>;
}
}
//导航注册
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
运行效果:
3,添加一个新的页面
class ChatScreen extends React.Component {
static navigationOptions = {
title: 'Chat with Lucy',
};
render() {
return (
<View>
<Text>Chat with Lucy</Text>
</View>
);
}
}
4,在HomeScreen中添加一个button组件,使用routeName Chat关联到ChatScreen。
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
</View>
);
}
}
这段代码主要是给Button绑定onPress事件。这时候,我们使用的两个跳转的页面需要在StackNavigator进行注册:
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },//新添加的页面
});
所以完整的代码是:
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',//设置标题内容
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Navigation!</Text>
<Button
onPress={() => navigate('Chat',{user:'Lucy'})}
title="Chat with Lucy"/>
</View>
);
}
}
const SimpleApp = StackNavigator({
Home: {screen: HomeScreen},
Chat:{screen:ChatScreen},
});
参数传递
在页面的跳转过程中,往往会伴随着参数的传递。
navigation参数传递
1,在第一个页面定义参数,将参数传值给需要传值的页面
constructor(props) {
super(props);
this.state = {};
}
...
if(navigator) {
navigator.push({
name: 'SecondPageComponent',
component: SecondPageComponent,
params:{
user:this.state.user,
pwd:this.state.pwd
}
})
}
2,如果需要监听页面的state状态
onChangeText={(text) => this.setState({user: text})}
3,另一个页面接受参数
componentDidMount() {
//这里获取从FirstPageComponent传递过来的参数: id
this.setState({
user:this.props.user,
pwd:this.props.pwd
});
}
4,去的传过来的值:
value={this.state.user }
react-navigation参数传递
对于 react-navigation参数的传递,使用上比较简单,只需要在navigate中加一个json格式的对象即可,如:
navigate('Chat', { user: 'Lucy' })
然后在接收的页面:
class ChatScreen extends React.Component {
static navigationOptions = {
// Nav options can be defined as a function of the navigation prop:
title: ({ state }) => `Chat with ${state.params.user}`,
};
render() {
// The screen's current route is passed in to `props.navigation.state`:
const { params } = this.props.navigation.state;
return (
<View>
<Text>Chat with {params.user}</Text>
</View>
);
}
}
所以,你就可以看到如下的效果:
TabNavigator
TabNavigator类似于底部导航效果
// 注册tabs
const Tabs = TabNavigator({
Home: {
screen: Home,
navigationOptions: { // 也可以写在组件的static navigationOptions内
tabBar: {
label: '首页',
icon: ({tintColor}) => (<Image source={require('./app/images/home.png')} style={[{tintColor: tintColor},styles.icon]}/>),
},
}
},
Bill: {
screen: Bill,
navigationOptions: {
tabBar: {
label: '账单',
icon: ({tintColor}) => (<Image source={require('./app/images/bill.png')} style={[{tintColor: tintColor},styles.icon]}/>),
},
}
},
Me: {
screen: Me,
navigationOptions: {
tabBar: {
label: '我',
icon: ({tintColor}) => (<Image source={require('./app/images/me.png')} style={[{tintColor: tintColor},styles.icon]}/>),
},
}
}
}, {
animationEnabled: false, // 切换页面时是否有动画效果
tabBarPosition: 'bottom', // 显示在底端,android 默认是显示在页面顶端的
swipeEnabled: false, // 是否可以左右滑动切换tab
backBehavior: 'none', // 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
tabBarOptions: {
activeTintColor: '#ff8500', // 文字和图片选中颜色
inactiveTintColor: '#999', // 文字和图片未选中颜色
showIcon: true, // android 默认不显示 icon, 需要设置为 true 才会显示
indicatorStyle: {
height: 0 // 如TabBar下面显示有一条线,可以设高度为0后隐藏
},
style: {
backgroundColor: '#fff', // TabBar 背景色
// height: 44
},
labelStyle: {
fontSize: 10, // 文字大小
},
},
});
DrawerNavigator
DrawerNavigator类似于抽屉侧滑效果。
const DrawerNav = DrawerNavigator({
Home: { screen: Home },
Bill: { screen: Bill },
Me: { screen: Me },
HomeTwo: { screen: HomeTwo },
HomeThree: { screen: HomeThree },
HomeFour: { screen: HomeFour },
BillTwo: { screen: BillTwo },
BillThree: { screen: BillThree }
}, {
drawerWidth: 200, // 抽屉宽
drawerPosition: 'left', // 抽屉在左边还是右边
// contentComponent: CustomDrawerContentComponent, // 自定义抽屉组件
contentOptions: {
initialRouteName: Home, // 默认页面组件
activeTintColor: 'white', // 选中文字颜色
activeBackgroundColor: '#ff8500', // 选中背景颜色
inactiveTintColor: '#666', // 未选中文字颜色
inactiveBackgroundColor: '#fff', // 未选中背景颜色
style: { // 样式
}
}
});
iOS版设置
在iOS中使用react-navigation需要注意以下几点:
使用Xcode设置Schemes;
在AppDelegate添加一下代码:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
js组件在注册路由时设置唯一的路径path, 例如Home2: { screen: Home2, path:’app/Home2’ };
在手机浏览器访问demo4://app/Home2, 弹窗选择打开, 就可以打开demo4 app并进到Home2页面。
react-native-tab-navigator
直接上代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import TabNavigator from 'react-native-tab-navigator';
import {
AppRegistry,
StyleSheet,
Text,
Image,
View
} from 'react-native';
const TabNavigatorItem =TabNavigator.Item;
//默认选项
const TAB_HOME_NORMAL=require('./image/tabbar_homepage.png');
const TAB_MINE_NORMAL=require('./image/tabbar_mine.png');
//选中
const TAB_HOME_PRESS=require('./image/tabbar_homepage_selected.png');
const TAB_MINE_PRESS=require('./image/tabbar_mine_selected.png');
export default class HelloWord extends Component {
//默认选中
constructor(){
super();
this.state={
selectedTab:'Home',
}
}
//点击方法
onPress(tabName){
if(tabName){
this.setState({
selectedTab:tabName,
}
);
}
}
//渲染选项
renderTabView(title,tabName,tabContent,isBadge){
var tabNomal;
var tabPress;
switch (tabName) {
case 'Home':
tabNomal=TAB_HOME_NORMAL;
tabPress=TAB_HOME_PRESS;
break;
case 'Mine':
tabNomal=TAB_MINE_NORMAL;
tabPress=TAB_MINE_PRESS;
break;
default:
}
return(
<TabNavigatorItem
selected={this.state.selectedTab===tabName}
title={title}
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={()=><Image style={styles.icon} source={tabNomal}/>}
renderSelectedIcon={()=><Image style={styles.icon} source={tabPress}/>}
onPress={()=>this.onPress(tabName)}
renderBadge={()=>isBadge?<View style={styles.badgeView}><Text style={styles.badgeText}>15</Text></View>:null}
>
<View style={styles.page}><Text>{tabContent}</Text></View>
</TabNavigatorItem>
);
}
//自定义TabView
tabBarView(){
return (
<TabNavigator
tabBarStyle={styles.tab}
>
{this.renderTabView('首页','Home','首页模块',true)}
{this.renderTabView('我的','Mine','我的模块',false)}
</TabNavigator>
);
}
//渲染界面
render() {
var tabView=this.tabBarView();
return (
<View style={styles.container}>
{tabView}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
tabText: {
fontSize: 10,
color: 'black'
},
selectedTabText: {
fontSize: 10,
color: 'green'
},
tab:{
height: 52,
alignItems:'center',
backgroundColor:'#f4f5f6',
},
tabIcon:{
width:25,
height:25,
},
badgeView:{
width:22,
height:14 ,
backgroundColor:'#f85959',
borderWidth:1,
marginLeft:10,
marginTop:3,
borderColor:'#FFF',
alignItems:'center',
justifyContent:'center',
borderRadius:8,
},
badgeText:{
color:'#fff',
fontSize:8,
},
icon: {
width: 22,
height: 22
},
page: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFFFFF'
},
});
AppRegistry.registerComponent('HelloWord', () => HelloWord);
参考:React Native页面参数传递
https://reactnavigation.org/docs/intro/
引用原文:http://blog.csdn.net/xiangzhihong8/article/details/71249167?ref=myread
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
React Native导航器之react-navigation使用的更多相关文章
- React Native 系列(二) -- React入门知识
前言 本系列是基于React Native版本号0.44.3写的,最初学习React Native的时候,完全没有接触过React和JS,本文的目的是为了给那些JS和React小白提供一个快速入门,让 ...
- React-Native(三):React Native是基于React设计的
React Native是基于React js设计的. 参考:<React 入门实例教程> React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript ...
- react native 导航路由组件react-navigation的使用
navigation的几个难点和问题: 1.底部tab是否可以加上中间的大按钮? 如果加上,如何触发事件? js文件放哪? 2.navigation的登录注册页面.成功后应该不能返回刚刚的登录页面?清 ...
- 【React Native开发】React Native控件之DrawerLayoutAndroid抽屉导航切换组件解说(13)
),请不要反复加群! 欢迎各位大牛,React Native技术爱好者增加交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送! 该DrawerLayoutAndroid组件封 ...
- React Native开发 - 搭建React Native开发环境
移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...
- 【React Native开发】React Native For Android环境配置以及第一个实例(1)
年9月15日也公布了ReactNative for Android,尽管Android版本号的项目公布比較迟,可是也没有阻挡了广大开发人员的热情.能够这样讲在2015年移动平台市场上有两个方向技术研究 ...
- 【React Native开发】React Native应用设备执行(Running)以及调试(Debugging)(3)
),React Native技术交流4群(458982758),请不要反复加群.欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文章 ...
- 【React Native开发】React Native控件之ListView组件解说以及最齐全实例(19)
),React Native技术交流4群(458982758).请不要反复加群!欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文章 ...
- 【React Native开发】React Native进行签名打包成Apk
转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50525976 本文出自:[江清清的博客] (一)前言 [好消息]个人 ...
随机推荐
- 如何让VS检查函数和类Comment的添加情况
问题: 现在有一个大的项目,我不能确定是否每个类和函数是否已经加上了comments,是否每个comments都是标注正确的. VS中有没有检查Comments的功能? 解决方案: 1.右击proje ...
- null!= xxx 和 xxx!=null有什么区别?
从意义上将没有区别,从编程规范上讲,第一种写法是为了防止写成:null = xxx
- 160704、commons-beanutils.jar常用方法
package com.test.beanutils; import java.lang.reflect.InvocationTargetException;import java.text.Pars ...
- angular做的简单购物车
虽然本人也是刚刚才开始学习angular.js,并不是非常会,但是这并不能阻止我对angular的喜爱.因为它太省代码了,比如说一个比较简单的购物车,就是只有商品名称,单价,数量,小计,总计和删除功能 ...
- ubuntu搭建java web环境
java web环境即jdk+tomcat+mysql jdk:http://www.oracle.com/technetwork/java/javase/downloads/index.html t ...
- 通过手机浏览器打开APP或者跳转到下载页面.md
目录 通过手机浏览器打开APP或者跳转到下载页面 添加 schemes 网页设置 参考链接 通过手机浏览器打开APP或者跳转到下载页面 以下仅展示最简单的例子及关键代码 由于硬件条件有限,仅测试了 A ...
- 2015-04-14——css3 @media
//判断横竖屏 @media screen and (min-aspect-ratio: 13/13) { body {background-color:red;}} //屏幕宽高比,必须是除数形式 ...
- 我的Android进阶之旅------>Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换)
Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换) 有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写. 下面是一个Java ...
- python collection 和 heapq 模块使用说明
一 :集合库collection python 拥有一些内置的数据类型,collections模块提供啦几个额外的数据类型: 1,namedtuple 生成可以使用名字来访问元素内容的tuple子 ...
- mysql 建立表之间关系 一对一 练习2
创建db5数据库 create database db5 charset=utf8; use db5; 例二:一个管理员唯一对应一个用户 用户表: id user password 1 egon xx ...