ReactNative导航新宠儿react-navigation
导航一直是App
开发中比较重要的一个组件,ReactNative
提供了两种导航组件供我们使用,分别是:NavigatorIOS
和Navigator
,但是前者只能用于iOS
平台,后者在ReactNative
0.44版本以后已经被移除了。好在有人提供了更好的导航组件,就是我们今天要讲的react-navigation
,并且ReactNative
官方更推荐我们使用此组件。
本篇文章只讲解基础用法,如果你想了解更多,请戳这里->戳我。
简介
react-navigation
主要包括导航,底部tab
,顶部tab
,侧滑等,功能很强大,而且体验接近原生。今天我们介绍的组件分别为:
- 导航 -> StackNavigator
- 底部或者顶部
tab
-> TabNavigator - 侧滑 -> DrawerNavigator
DrawerNavigator
先来看看运行效果:
这里,我们定义三个界面,一个为根界面,一个主界面,一个侧滑界面,分别如下:
侧滑界面DrawerLeftPage.js:
|
这个界面很简单,我们定义了一个按钮,点击按钮的时候,关闭侧滑页,这里关闭的参数为DrawerClose
,通过props
属性可以拿到当前navigation
。另外我们又定义了一个静态属性,来配置侧滑显示的具体属性。注意,此属性名一定要写成navigationOptions
。
navigationOptions
主要有以下参数:
title
:通用标题,当你不写drawerLabel
时,使用此参数作为侧滑标题,通常都不写drawerLabel
:侧滑标题drawerIcon
:侧滑的标题图标,这里会回传两个参数,{focused: boolean, tintColor: string}
,focused
表示是否是选中状态,tintColor
表示选中的颜色,这个颜色是我们自己在根视图定义的。当然,你也可以使用其他的组件来作为图标,比如Text
。
主界面 DrawerHomePage.js
|
这个界面和上一个界面基本一样,只是这里的点击事件为打开抽屉,传的参数为DrawerOpen
。
打开侧滑:this.props.navigation.navigate('DrawerOpen')
关闭侧滑:this.props.navigation.navigate('DrawerClose')
根视图 DrawerPage.js
|
这里我们从react-navigation
导入侧滑组件DrawerNavigator
,这里我们定义一个常量Drawer
,主要来配置侧滑的各种参数。首先,看DrawerNavigator
的构造方法:DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
这里接收两个参数,一个为页面路由配置,一个为显示的配置,我们分别来看,
RouteConfigs
:
这里你可以配置所有的界面,例如,当前例子配置了两个界面:Home
和Left
,指定界面分别为DrawerHomePage
和DrawerLeftPage
。你还可以配置其他界面,这些配置的界面都将显示在侧滑栏上。
DrawerNavigatorConfig
:
drawerWidth
: 侧滑栏的宽度,如果你不想写死,可以使用Dimensions
获取屏幕的宽度,动态计算drawerPosition
: 侧滑的方向,left
和right
,默认left
contentComponent
: 这个就比较重要了,可以自定义侧滑页,我们等会详细说。contentOptions
: 主要配置侧滑栏条目的属性,只对DrawerItems
,例如我们刚才写的例子,就可以通过这个属性来配置颜色,背景色等。其主要属性有:items
: 这个我也没弄清是什么意思,不影响activeItemKey
: 定义当前选中的页面的keyactiveTintColor
: 选中条目状态的文字颜色activeBackgroundColor
: 选中条目的背景色inactiveTintColor
: 未选中条目状态的文字颜色inactiveBackgroundColor
: 未选中条目的背景色onItemPress
: 选中条目的回调,这个参数属性为函数,会将当前路由回调过去style
: 定义条目的颜色labelStyle
: 定义条目文字的颜色
例如:
|
如此,DrawerNavigator
的基本用法我们已经搞的差不多了,但是,这还不能满足我们的日常开发,因为我们的侧滑界面可不是这个样子的。
刚才还有个参数没有介绍,就是contentComponent
,他就是用来自定义侧滑界面的。
上面的例子有一个问题,加入我们的item
比较多,但是侧滑页面并不能滑动,这时,就要使用contentComponent
来自定义界面,如下:
|
运行效果如下:
当然,我们完全可以自定义侧滑界面,并且不使用DrawerItems
条目。如下:
|
我们这里定义了一个常量,返回DrawerLeftPage
作为我们的侧滑界面,在DrawerLeftPage
中就可以随意定制了。注意,一定要将props
传递到下一个界面,否则通过props
拿不到navigation
。最终运行效果:
好了,DrawerNavigator
我们已经了解完了。
StackNavigator
这个组件就比较麻烦了,我们先来看他的构造函数:StackNavigator(RouteConfigs, StackNavigatorConfig)
RouteConfigs:
它主要是来配置页面路由的,类似与Android
的Manifest.xml
,所有的界面都必须配置在里面。如下:
|
这里我们配置了首页和第二个页面,并且配置了标题参数。当然,如果你不想在路由里面配置页面的参数,你也可以在页面中配置,需要在页面中定义一个静态常量navigationOptions
,和DrawerNavigator
的使用方法类似。我们来看看navigationOptions
有哪些可以配置的参数:
title
: 这个即可以作为头部标题,也可以作为返回标题和Tab
标题header
: 自定义导航条,系统的导航条会隐藏headerTitle
: 标题headerBackTitle
: 回退标题headerTruncatedBackTitle
: 当回退标题不能显示的时候显示此属性的标题,比如回退标题太长了headerRight
: 定义导航栏右边视图headerLeft
: 定义导航栏左边视图headerStyle
: 定义导航栏的样式,比如背景色等headerTitleStyle
: 定义标题的样式headerBackTitleStyle
: 定义返回标题的样式headerTintColor
: 定义导航条的tintColor,会覆盖headerTitleStyle
中的颜色gesturesEnabled
: 定义是否能侧滑返回,iOS
默认true
,Android
默认false
示例如下:
|
StackNavigatorConfig
这个参数主要是配置整个路由的,包括跳转动画,跳转方式等。先来看看它有哪些参数:
initialRouteName
: 初始化哪个界面为根界面,如果不配置,默认使用RouteConfigs
中的第一个页面当做根界面initialRouteParams
: 初始化根界面参数,主要是给根视图传递一些参数,通过this.props.navigation.state.params
可以取到navigationOptions
: 配置默认的navigationOptions
paths
: 官方意思是覆盖已经配置的路由,可是我没有试出来效果mode
: 跳转方式,一种是card
,默认的,在iOS
上是从右到左跳转,在Android
上是从下到上,都是使用原生系统的默认跳转方式。一种是modal
,只针对iOS
平台,模态跳转。headerMode
: 跳转过程中,导航条的动画效果,有三个值,float
表示会渐变,类似于iOS
的原生效果,screen
表示没有渐变。none
表示隐藏导航条cardStyle
: 可以统一定义界面的颜色,例如背景色transitionConfig
:配置页面跳转的动画onTransitionStart
: 页面跳转动画即将开始的回调onTransitionEnd
: 页面跳转动画结束的回调
|
Navigation Prop
了解完路由配置以后,我们再来看看组件的属性,
navigate
:路由方法,主要来启动另一个页面state
:状态,其实StackNavigator
内部维护了两个路由栈,一个名为newState
,是当前显示页面之前的所有页面,包括当前界面。一个名为lastState
,当然,通过state
还能拿到很多参数。setParams
: 设置参数,记住,一定不要在render
方法中调用此方法。goBack
: 返回dispatch
: 给当前界面设置action,会替换原来的跳转,回退等事件
navigate
此方法可以传三个参数:navigate(routeName, params, action)
routeName
: 页面名称,一定要在路由配置中配置。params
: 传递参数到下一个页面action
:action
例如:
|
state
通过state
,我们能拿到传递过来的参数,通过打印state
,得到如下结果:
可以看到,通过state
,我们可以拿到传递过来的params
setParams
设置当前页面的参数,记住,调用此方法一定要在componentDidMount
|
goBack
回退到指定界面,如果什么都不传,回退到上一个界面,传null
,回退到任意界面。传key
,可以回退到指定界面。例如:
|
关于react-navigation
的基本用法已经了解的差不多了,至于更详细的用法,可以看官方文档。
注意:
全屏侧滑返回手势:系统默认有侧滑返回手势,距离屏幕距离为35,为了使用全屏侧滑,需要修改源码:在react-navigation/src/views/CardStack.js
类,修改常量GESTURE_RESPONSE_DISTANCE_HORIZONTAL
为Dimensions.get('window').width
即可。
在iOS
上,标题会居中,但是在Android
上是居左的,想要Android
上也居中,需要修改:react-navigation/src/views/Header.js
中的title
样式修改为center
,并且在方法_renderTitle
中注释掉
|
这几句代码。
TabNavigator
tab
选项卡的功能,在iOS
上默认类似于TabBar
,在Android
中类似于TabLayout
,先来看看构造方法:
|
RouteConfigs
同样的,还是配置路由,如下:
|
当然,你也可以配置navigationOptions
,但是,在这里配置的优先级比在页面中配置的优先级高,所以,我们一般再单个页面中配置所有的navigationOptions
。
TabNavigatorConfig
tabBarComponent
: 默认两种方式,TabBarBottom
和TabBarTop
,可以通过如下代码导入:import {TabBarBottom,TabBarTop} from 'react-navigation';
,这两者的区别主要是样式和位置的区别,iOS
上默认使用TabBarBottom
,Android
上默认使用TabBarTop
。tabBarPosition
: 配置tab
的位置,top
和bottom
swipeEnabled
: 是否可以滑动切换tab
animationEnabled
: 点击选项卡切换界面是否需要动画lazy
: 是否懒加载界面,默认一次加载所有的界面,我们最好设置为truetabBarOptions
:tab
的样式等配置,我们下面详细说initialRouteName
,第一次初始化哪个界面,默认初始化第一个。order
,tab
排序,默认使用配置路由的顺序paths
: 配置pathbackBehavior
,当Android
点击返回键的时候,做的处理,initialRoute
返回到初始化的界面,none
退出应用
例子如下:
|
tabBarOptions
这个参数主要配置样式,针对TabBarBottom
和TabBarTop
。
TabBarBottom
:
activeTintColor
: 选中的文字颜色activeBackgroundColor
: 选中的背景色inactiveTintColor
: 未选中的文字颜色inactiveBackgroundColor
: 未选中的背景色showLabel
: 是否显示标题,默认显示style
: 定义item的样式labelStyle
: 标题的样式
例如:
TabBarTop
:
activeTintColor
: 选中的文字颜色inactiveTintColor
: 未选中的文字颜色showIcon
: 是否显示图标,默认显示showLabel
: 是否显示标题,默认显示upperCaseLabel
: 使用大写字母pressColor
: 定义颜色,大于Android5.0
的一种按压效果pressOpacity
: 按压下去的透明度,在iOS
或者Android5.0
之前scrollEnabled
: 是否能够滚动,类似于今日头条的标题头tabStyle
: 定义item
的样式indicatorStyle
: 指示器的颜色labelStyle
: 文字的样式iconStyle
: 图标的样式style
: 定义tab
的样式
例如:
NavigationOptions
当然,通过NavigationOptions
来配置我们的tabBarItem
:
title
: 标题tabBarVisible
: 是否可见tabBarIcon
: 配置图片,当然,完全可以不使用图片tabBarLabel
: 也是配置标题,只不过title
既能配置tab
的标题,也能配置navigation
的标题
例如:
好了,TabNavigator
也说的差不多了。当然,如果你想在某个界面切换tab
,使用如下方法:
仿QQ主界面
下面的例子是仿QQ
主界面的,当然包括本篇文章的实例代码,请戳这里->戳我。
运行效果: