我们使用 react-navigation 这个目前很流行的三方库,下面我们介绍他提供的 TabNavigator + StackNavigator 来实现界面跳转、Tab的切换。
参照文章:https://www.jianshu.com/p/2f575cc35780
安装
通过命令安装:
1 | npm install --save react-navigation |
使用
创建 MainTab.js 用来自定义 TabNavigator(类似于iOS中的Tab)
1 | import React from 'react'; |
创建 AppIndex.js 来自定义 StackNavigator(类似于iOS中的Navigator)
1 | import React from 'react'; |
配置入口
做完上面操作后,我们需要在 index.ios.js 和 index.android.js 里面配置启动初始化界面
1 |
|
分析
对于 iOS 中 Tab + Nav 这样的组合,初始化顺序是:先初始化几个 Nav(里面嵌了各个主页面),然后把这初始化的几个 Nav 在添加分配到 Tab 上面,这样每个 Tab 控制一个根 Nav,每个根 Nav 下面就可以控制跳转了。
但是我们看上面的初始化和配置入口:
1、在 AppIndex 里面 Home 的 screen 给的是 MainNavigator(MainNavigator就包含了4个Tab)
2、配置入口里面配置是 AppIndex,那配置的是 Nav
这和上面我说的 iOS 的标准流程是反的,我不知道按 iOS 的配置行不行,没有试过。
API 分析
TabNavigator
他有一个创建方法 TabNavigator(NavigationRouteConfigMap,TabNavigatorConfig),我们可以通过此函数创建和导出我们需要的。
下面来看看 TabNavigatorConfig 的属性
1、screen
对应界面名称,需要填入 import 之后的页面。
2、tabBarPosition
设置 tabbar 的位置,iOS 默认在底部,安卓默认在顶部(”top”, “bottom”)
3、swipeEnabled
是否允许在标签之间进行滑动
4、animationEnabled
是否在更改标签时显示动画
5、lazy
是否根据需要懒呈面标签,即 app 打开的时候将底部标签全部加载完,默认是 false,推荐 true
6、tabBarOptions
配置标签栏的一些属性
1、activeTintColor: 设置文字和图片选中颜色(前景色)
2、activeBackgroundColor: 设置文字和图片选中的背景色
3、inactiveTintColor: 设置文字和图片默认颜色(前景色)
4、inactiveBackgroundColor: 设置文字和图片默认的背景色
5、showLabel: 是否显示label,默认开启
6、style: tabbar 的样式
7、labelStyle: label 的样式
8、tabStyle: tab 的样式
9、showIcon: android 默认不显示 icon,需要设置为 true 才会显示
10、upperCaseLabel: 是否使标签大写,默认为 true
11、pressColor: material涟漪效果的颜色(android需要大于5.0)
12、pressOpacity: 按压标签的透明度变化(android需要大于5.0)
13、scrollEnabled: 是否启用可滚动选项卡
14、indicatorStyle: 标签指示器的样式对象(选项卡底部行),android底部会多出一条线,可以将height设置为0来临时解决这个问题
15、iconStyle: 图标样式
下面来看看 NavigationRouteConfigMap 的属性
navigationOptions
1、title: 标题,会同时设置导航栏和标签栏的title
2、tabBarVisible: 是否隐藏标签栏,默认不隐藏(true)
3、tabBarIcon: 设置标签栏的图片,需要每个都设置
4、tabBarLabel: 设置标签栏的title
StackNavigator
他和 TabNav 一样有相同的函数创建
StackNavigatorConfig
1、screen:
对应界面名称,需要填入import之后的页面
2、initialRouteName
设置默认的页面组件,必须是上面已经import过的
3、initialRouteParams
初始路由参数
4、navigationOptions
配置一些基本属性
5、path
类似于 deep link 的功能,对于 iOS 这边需要如下设置
1、在 Xcode 中设置相应的 schemes,即在 Info 下的 URL Types 里面添加一个 URL Schemes 名字,我们假定叫 Demo。
2、在 AppDelegate 里面添加如下代码
1 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { |
3、在 JS 代码的 path 里面设置跳转唯一路径,例如:Test: {screen: Test, path: ‘app/Test’};
这样设置完成后,就可以直接在手机浏览器访问 Demo://app/Test 就能打开 App,并进入到 Test 页面。
6、mode
定义跳转风格:
card: 使用 iOS 和 android 默认的风格
modal: iOS 独有的屏幕底部动画,类似于 present 效果
7、headerMode
返回上级页面时动画效果
float: iOS 默认的效果
screen: 滑动返回,整个页面都会返回
none:无动画,导航栏都隐藏了
8、cardStyle
自定义设置跳转效果
9、transitionConfig
自定义设置滑动返回的配置
10、onTransitionStart
当转换动画即将开始时被调用的功能
11、onTransitionEnd
当转换动画完成,将被调用的功能
navigationOptions
1、title
标题,如果设置了这个导航栏和标签栏的title就会变成一样的,不推荐使用
2、header
可以设置一些导航的属性,如果隐藏顶部导航栏只要将这个属性设置为 null
3、headerTitle
设置导航栏标题
4、headerBackTitle
设置跳转页面左侧返回箭头后面的文字,默认是上一个页面的标题。可以自定义,也可以设置为 null
5、headerTruncatedBackTitle
设置当上个页面标题不符合返回箭头后的文字时,默认改成”返回”
6、headerRight
设置导航条右侧。可以是按钮或者其他视图控件
7、headerLeft
设置导航条左侧。可以是按钮或者其他视图控件
8、headerStyle
设置导航条的样式。背景色,宽高等
9、headerTitleStyle
设置导航栏文字样式,安卓上如果要设置文字居中,只要添加 alignSelf: ‘center’ 就可以了,如果左边有返回箭头导致文字还是没有居中的问题,最简单的解决思路就是在右边也放置一个空的View占位就行,代码如下:
1 | static navigationOptions = { |
不过在最新的版本中,可以通过如下代码来让其居中了
1 | flex:1, |
10、headerBackTitleStyle
设置导航栏‘返回’文字样式
11、headerTintColor
设置导航栏颜色
12、gesturesEnabled
是否支持滑动返回手势,iOS默认支持,安卓默认关闭
界面跳转(传值和取值)
在界面组件注入 StackNavigator 中时,界面组件就被赋予了 navigation 这个属性,即在界面组件中可以通过 this.props.navigation 获取并进行一些操作。
1、通过 navigate 实现页面跳转
1 | this.props.navigation.navigate('Test') |
其中 ‘Test’ 是我们注入的界面组件的名称(不是screen)
2、返回上一页
1 | this.props.navigation.goBack() |
3、传值
1 | this.props.navigation.navigate('Test', {user: 'xxx', name: 'yyy'}) |
4、取值
1 | this.props.navigation.state.params.user |
自定义导航栏返回按钮
项目中基本是没有可能用自带的那个导航栏返回按钮的,因为他永远是蓝色的,我们可以使用下面的属性来更改:
通过更改属性来自定义
1、更改返回按钮颜色(那个左箭头)
1 | navigationOptions: ({navigation}) => ({ |
通过 headerTintColor 来更改
2、很多不想显示左边返回的文字
1 | navigationOptions: ({navigation}) => ({ |
我们通过更改 headerBackTitleStyle 的样式,颜色设置成透明就好了
通过添加控件来自定义
我们添加自己的控件和图片来自定义
1 | const StackOptions = ({navigation}) => { |
然后在下面的地方调用一下就可以自定义导航栏返回按钮了
1 | const MyApp = StackNavigator({ |
自定义Tabbar
Tabbar在选中状态时可不可以设置其他图标,官方文档里面 tabBarIcon 除了了 tintColor 还有另外一个属性,用来判断选中状态的 focused
1 | focused ? |
通过判断 focused, 选中状态下使用 A 图片,未选中使用 B 图片。
封装一下:
1 | export const TabOptions = (tabBarTitle,normalImage,selectedImage,navTitle) => { |
总结
我们发现导航栏要跳转的页面,都需要提前注册好,万一我们想动态跳转怎么办?
我也不知道,还在研究中~~~~
此库提供的功能很多、很强大,上面也只是列举了一部分,还有好大一部分需要研究。
待更新……