react-navigation
react-navigation是今年1月份新出的一款React-native导航组件,才几个月github就三千多star,半官方身份,fb推荐使用,据称性能和效果跟原生差不多. 可能是react-native导航组件的未来主流. 但现在还是beta版本(最新v1.0.0-beta.7
) 坑还比较多,文档和参考资料较少. 正式项目使用还需慎重.http://www.jianshu.com/p/7d435e199c96
有问题找issues,基本上坑都在这里.
官方文档
主要构成
按使用形式主要分三部分:
1StackNavigator
: 类似于普通的Navigator,屏幕上方导航栏
2TabNavigator
: 相当于iOS里面的TabBarController,屏幕下方的标签栏
3DrawerNavigator
: 抽屉效果,侧边滑出
StackNavigator 导航栏
API:StackNavigator(RouteConfigs,StackNavigatorConfig)
const Navs = StackNavigator({ Home: { screen: Tabs },HomeTwo: { screen: HomeTwo, path:'app/homeTwo',使用url导航时用到,如 web app 和 Deep Linking navigationOptions: {} },HomeThree: { screen: HomeThree },HomeFour: { screen: HomeFour } },{ initialRouteName: 'Home',161);">// 默认显示界面 navigationOptions: { header: { backTitle: '返回',161);">// 左上角返回键文字 style: { backgroundColor: '#fff' },titleStyle: { color: 'green' } },cardStack: { gesturesEnabled: true } },mode: 'card',161);">// 页面切换模式,左右是card(相当于iOS中的push效果),上下是modal(相当于iOS中的modal效果) headerMode: 'screen',161);">// 导航栏的显示模式,screen: 有渐变透明效果,float: 无透明效果,none: 隐藏导航栏 onTransitionStart: ()=>{ console.log('导航栏切换开始'); },161);">// 回调 onTransitionEnd: '导航栏切换结束'); } });
});
navigationOptions
参数:
-
title
: 导航栏的标题
-
header
: 导航栏设置对象
visible
: 导航栏是否显示
title
: 导航栏的标题,可以是字符串也可以是个组件
backTitle
: 左上角的返回键文字,默认是上一个页面的title
right
: 导航栏右按钮
left
: 导航栏左按钮
style
: 导航栏的style
titleStyle
: 导航栏的title的style
tintColor
: 导航栏颜色
-
cardStack
: 配置card stack
gesturesEnabled
: 是否允许右滑返回,在iOS上默认为true,在Android上默认为false
在组件中设置static navigationOptions
示例:
static navigationOptions = { title: 'homeThree',header: (navigation,defaultHeader) => ({ ...defaultHeader,161);">// 默认预设 visible: true }),102);">false } }; static navigationOptions = { title: (// 动态标题 if (navigation.state.params.isSelected) { return `${navigation.state.params.name}选中`; } else { ${navigation.state.params.name}没选中`; } },102);">{ state,setParams,goBack }) => { let right; if (state.params.isSelected) { right = (<Button title="取消" onPress={() => setParams({ isSelected: false })}/>); } else { right = ("选择" onPress={() => setParams({ isSelected: true })}/>); } let left = ("返回" onPress={() => goBack()}/>); let visible = false; return { right,left,visible }; },161);">// header: {left: <Button title="返回"/>}, };
StackNavigatorConfig
initialRouteName
: 设置默认的页面组件,必须是上面已注册的页面组件
initialRouteParams
: 初始路由的参数
navigationOptions
: 屏幕导航的默认选项
paths
: RouteConfigs里面路径设置的映射
mode
: 页面切换模式:
card
: 普通app常用的左右切换
modal
: 上下切换
headerMode
: 导航栏的显示模式:
float
: 无透明效果,默认
screen
: 有渐变透明效果,如微信QQ的一样
none
: 隐藏导航栏
cardStyle
: 样式
onTransitionStart
: 页面切换开始时的回调函数
onTransitionEnd
: 页面切换结束时的回调函数
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: '账单',152);">'./app/images/bill.png'
)} style={[{tintColor: tintColor},Me: {
screen: Me,152);">'我',152);">'./app/images/me.png')} style={[{tintColor: tintColor},}
}
},{
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抽屉
const DrawerNav = DrawerNavigator({
Home: { screen: Home }, Bill: { screen: Bill },22);"> Me: { screen: Me },22);"> HomeTwo: { screen: HomeTwo },22);"> HomeThree: { screen: HomeThree },22);"> HomeFour: { screen: HomeFour },22);"> BillTwo: { screen: BillTwo },22);"> BillThree: { screen: BillThree }
},{
drawerWidth: 200,161);">// 抽屉宽
drawerPosition: 'left',161);">// 抽屉在左边还是右边
contentOptions: {
initialRouteName: Home,161);">// 默认页面组件
activeTintColor: 'white',161);">// 选中文字颜色
activeBackgroundColor: // 选中背景颜色
inactiveTintColor: '#666',161);">// 未选中文字颜色
inactiveBackgroundColor: // 未选中背景颜色
style: {
}
}
});
navigation
在StackNavigator
中注册后的组件都有navigation
这个属性.navigation
又有5个参数:navigate
,goBack
,246);">state,246);">setParams,246);">dispatch,可以在组件下console.log
一下this.props
就能看到.
this.props.navigation.navigate('Two',{ name: 'two' }): push下一个页面
routeName
: 注册过的目标路由名称
params
: 传递的参数
action
: 如果该界面是一个navigator的话,将运行这个sub-action
-
this.props.navigation.goBack()
: 返回上一页
-
this.props.navigation.state
: 每个界面通过这去访问它的router,state其中包括了:
routeName
: 路由名
key
: 路由身份标识
params
: 参数
-
this.props.navigation.setParams
: 该方法允许界面更改router中的参数,可以用来动态的更改导航栏的内容
-
this.props.navigation.dispatch
: 可以dispatch一些action,主要支持的action有:
-
Navigate
:
import { NavigationActions } from 'react-navigation'
const navigationAction = NavigationActions.navigate({
routeName: 'Profile',params: {},161);">// 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方法会清除原来的路由记录,添加上新设置的路由信息,可以指定多个action,index是指定默认显示的那个路由页面,注意不要越界了
import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 0,actions: [
NavigationActions.navigate({ routeName: 'Profile'}),NavigationActions.navigate({ routeName: 'Two'})
]
})
this.props.navigation.dispatch(resetAction)
-
SetParams
: 为指定的router更新参数,该参数必须是已经存在于router的param中
const setParamsAction = NavigationActions.setParams({
// these are the new params that will be merged into the existing route params
key: 'screen-123',})
this.props.navigation.dispatch(setParamsAction)
Navigation Actions
- 支持以下actions:
Navigate
:
Reset
:
Back
:
Set Params
:
Init
:
Deep Link
其他app或浏览器使用url打开次app并进入指定页面. 如浏览器输入urldemo4://home/home3
直接进入home3
页面.
iOS版设置
- 使用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
页面了.