在React Native 中,官方已经推荐使用react-navigation 来实现各个界面的跳转和不同板块的切换。react-navigation 主要包括三个组件:
-
StackNavigator 导航组件
-
TabNavigator 切换组件
-
DrawerNavigator 抽屉组件
StackNavigator 用于实现各个页面之间的跳转,TabNavigator 用来实现同一个页面上不同界面的切换,DrawerNavigator 可以实现侧滑的抽屉效果。
StackNavigator
StackNavigator 组件采用堆栈式的页面导航来实现各个界面跳转。它的构造函数:
1
|
StackNavigator(RouteConfigs,StackNavigatorConfig)
|
有RouteConfigs 和StackNavigatorConfig 两个参数。
RouteConfigs
RouteConfigs 参数表示各个页面路由配置,类似于android原生开发中的AndroidManifest.xml ,它是让导航器知道需要导航的路由对应的页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
const RouteConfigs = { Home: { screen: HomePage, navigationOptions: ({navigation}) => ({ title: '首页', }), }, Find: { screen: FindPage, navigationOptions: ({navigation}) => ({ title: '发现', Mine: { screen: MinePage, navigationOptions: ({navigation}) => ({ title: '我的', };
|
这里给导航器配置了三个页面,Home 、Find 、Mine 为路由名称,screen 属性值HomePage 、FindPage 、MinePage 为对应路由的页面。
navigationOptions 为对应路由页面的配置选项:
-
title - 可以作为头部标题headerTitle ,或者Tab标题tabBarLabel
-
header - 自定义的头部组件,使用该属性后系统的头部组件会消失
-
headerTitle - 头部的标题,即页面的标题
-
headerBackTitle - 返回标题,默认为title
-
headerTruncatedBackTitle - 返回标题不能显示时(比如返回标题太长了)显示此标题,默认为“Back”
-
headerRight - 头部右边组件
-
headerLeft - 头部左边组件
-
headerStyle - 头部组件的样式
-
headerTitleStyle - 头部标题的样式
-
headerBackTitleStyle - 头部返回标题的样式
-
headerTintColor - 头部颜色
-
headerPressColorAndroid - Android 5.0 以上MD风格的波纹颜色
-
gesturesEnabled - 否能侧滑返回,iOS 默认true ,Android 默认false
StackNavigatorConfig
StackNavigatorConfig 参数表示导航器的配置,包括导航器的初始页面、各个页面之间导航的动画、页面的配置选项等等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
const StackNavigatorConfig = { initialRouteName: 'Home', initialRouteParams: {initPara: '初始页面参数'}, navigationOptions: { title: '标题', headerTitleStyle: {fontSize: 18,color: '#666666'}, headerStyle: {height: 48,backgroundColor: '#fff'}, paths: 'page/main', mode: 'card', headerMode: 'screen', cardStyle: {backgroundColor: "#ffffff"}, transitionConfig: (() => ({ screenInterpolator: CardStackStyleInterpolator.forHorizontal, })), onTransitionStart: (() => { console.log('页面跳转动画开始'); }), onTransitionEnd: (() => { console.log('页面跳转动画结束'); }), };
|
-
initialRouteName - 导航器组件中初始显示页面的路由名称,如果不设置,则默认第一个路由页面为初始显示页面
-
initialRouteParams - 给初始路由的参数,在初始显示的页面中可以通过this.props.navigation.state.params 来获取
-
navigationOptions - 路由页面的配置选项,它会被RouteConfigs 参数中的 navigationOptions 的对应属性覆盖。
-
paths - 路由中设置的路径的覆盖映射配置
-
mode - 页面跳转方式,有card 和modal 两种,默认为card :
-
card - 原生系统默认的的跳转
-
modal - 只针对iOS平台,模态跳转
-
headerMode - 页面跳转时,头部的动画模式,有float 、screen 、none 三种:
-
float - 渐变,类似iOS的原生效果
-
screen - 标题与屏幕一起淡入淡出
-
none - 没有动画
-
cardStyle - 为各个页面设置统一的样式,比如背景色,字体大小等
-
transitionConfig - 配置页面跳转的动画,覆盖默认的动画效果
-
onTransitionStart - 页面跳转动画即将开始时调用
-
onTransitionEnd - 页面跳转动画一旦完成会马上调用
页面的配置选项navigationOptions 通常还可以在对应页面中去静态配置,比如在HomePage 页面中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
export default class HomePage extends Component {
// 配置页面导航选项 static navigationOptions = ({navigation}) => ({ title: 'HOME', titleStyle: {color: '#ff00ff'}, headerStyle:{backgroundColor:'#000000'} });
render() { return ( <View></View> ) }; }
|
同样地,在页面里面采用静态的方式配置navigationOptions 中的属性,会覆盖StackNavigator 构造函数中两个参数RouteConfigs 和StackNavigatorConfig 配置的navigationOptions 里面的对应属性。navigationOptions 中属性的优先级是: 页面中静态配置 > RouteConfigs > StackNavigatorConfig
有了RouteConfigs 和StackNavigatorConfig 两个参数,就可以构造出一个导航器组件StackNavigator ,直接引用该组件:
1 2 3 4 5 6 7 8 9
|
const Navigator = StackNavigator(RouteConfigs,StackNavigatorConfig);
export default class MainComponent extends Component { render() { return ( <Navigator/> ) }; }
|
已经配置好导航器以及对应的路由页面了,但是要完成页面之间的跳转,还需要navigation 。
navigation
在导航器中的每一个页面,都有navigation 属性,该属性有以下几个属性/方法:
-
navigate - 跳转到其他页面
-
state - 当前页面导航器的状态
-
setParams - 更改路由的参数
-
goBack - 返回
-
dispatch - 发送一个action
navigete
调用这个方法可以跳转到导航器中的其他页面,此方法有三个参数: — routeName 导航器中配置的路由名称 — params 传递参数到下一个页面 — action action 比如:this.props.navigation.navigate('Find',{param: 'i am the param'});
state
state 里面包含有传递过来的参数params 、key 、路由名称routeName ,打印log可以看得到:
1 2 3 4 5
|
{ params: { param: 'i am the param' }, key: 'id-1500546317301-1', routeName: 'Mine' }
|
setParams
更改当前页面路由的参数,比如可以用来更新头部的按钮或者标题。
1 2 3
|
componentDidMount() { this.props.navigation.setParams({param:'i am the new param'}) }
|
goBack
回退,可以不传,也可以传参数,还可以传null 。
1 2 3
|
this.props.navigation.goBack(); // 回退到上一个页面 this.props.navigation.goBack(null); // 回退到任意一个页面 this.props.navigation.goBack('Home'); // 回退到Home页面
|
TabNavigator
TabNavigator ,即是Tab选项卡,类似于原生android 中的TabLayout ,它的构造函数:
1
|
TabNavigator(RouteConfigs,TabNavigatorConfig)
|
api和StackNavigator 类似,参数RouteConfigs 是路由配置,参数TabNavigatorConfig 是Tab选项卡配置。
RouteConfigs
路由配置和StackNavigator 中是一样的,配置路由以及对应的screen 页面,navigationOptions 为对应路由页面的配置选项:
-
title - Tab标题,可用作headerTitle 和tabBarLabel 回退标题
-
tabBarVisible - Tab的是否可见,没有设置的话默认为true
-
tabBarIcon - Tab的icon组件,可以根据{focused: boolean,tintColor: string} 方法来返回一个icon组件
-
tabBarLabel - Tab中显示的标题字符串或者组件,也可以根据{ focused: boolean,tintColor: string } 方法返回一个组件
TabNavigatorConfig
-
tabBarComponent - Tab选项卡组件,有TabBarBottom 和TabBarTop 两个值,在iOS中默认为TabBarBottom ,在Android中默认为TabBarTop 。
-
TabBarTop - 在页面的顶部
-
TabBarBottom - 在页面的底部
-
tabBarPosition - Tab选项卡的位置,有 top 或 bottom 两个值
-
swipeEnabled - 是否可以滑动切换Tab选项卡
-
animationEnabled - 点击Tab选项卡切换界面是否需要动画
-
lazy - 是否懒加载页面
-
initialRouteName - 初始显示的Tab对应的页面路由名称
-
order - 用路由名称数组来表示Tab选项卡的顺序,默认为路由配置顺序
-
paths - 路径配置
-
backBehavior - androd点击返回键时的处理,有initialRoute 和none 两个值
-
initailRoute - 返回初始界面
-
none - 退出
-
tabBarOptions - Tab配置属性,用在TabBarTop 和TabBarBottom 时有些属性不一致:
- 用于
TabBarTop 时:
-
activeTintColor - 选中的文字颜色
-
inactiveTintColor - 未选中的文字颜色
-
showIcon - 是否显示图标,默认显示
-
showLabel - 是否显示标签,默认显示
-
upperCaseLabel - 是否使用大写字母,默认使用
-
pressColor - android 5.0以上的MD风格波纹颜色
-
pressOpacity - android 5.0以下或者iOS按下的透明度
-
scrollEnabled - 是否可以滚动
-
tabStyle - 单个Tab的样式
-
indicatorStyle - 指示器的样式
-
labelStyle - 标签的样式
-
iconStyle - icon的样式
-
style - 整个TabBar的样式
- 用于
TabBarBottom 时:
-
activeTintColor - 选中Tab的文字颜色
-
activeBackgroundColor - 选中Tab的背景颜色
-
inactiveTintColor - 未选中Tab的的文字颜色
-
inactiveBackgroundColor - 未选中Tab的背景颜色
-
showLabel - 是否显示标题,默认显示
-
style - 整个TabBar的样式
-
labelStyle - 标签的样式
-
tabStyle - 单个Tab的样式
底部Tab导航示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
import React,{Component} from 'react'; import {StackNavigator,TabBarBottom,TabNavigator} from "react-navigation"; import HomeScreen from "./index18/HomeScreen"; import NearByScreen from "./index18/NearByScreen"; import MineScreen from "./index18/MineScreen"; import TabBarItem from "./index18/TabBarItem"; export default class MainComponent extends Component { render() { return ( <Navigator/> ); } }
const TabRouteConfigs = { Home: { screen: HomeScreen, navigationOptions: ({navigation}) => ({ tabBarLabel: '首页', tabBarIcon: ({focused,tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')} /> ), NearBy: { screen: NearByScreen, navigationOptions: { tabBarLabel: '附近',tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')} /> ), }, } , Mine: { screen: MineScreen, navigationOptions: { tabBarLabel: '我的',tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')} /> ), } }; const TabNavigatorConfigs = { initialRouteName: 'Home', tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', lazy: true, }; const Tab = TabNavigator(TabRouteConfigs,TabNavigatorConfigs); const StackRouteConfigs = { Tab: { screen: Tab, } }; const StackNavigatorConfigs = { initialRouteName: 'Tab', headerStyle: {backgroundColor: '#5da8ff'}, headerTitleStyle: {color: '#333333'}, } }; const Navigator = StackNavigator(StackRouteConfigs,StackNavigatorConfigs);
|
顶部Tab选项卡示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
import React,{Component} from "react"; import {StackNavigator,TabBarTop,TabNavigator} from "react-navigation"; import HomeScreen from "./index18/HomeScreen"; import NearByScreen from "./index18/NearByScreen"; import MineScreen from "./index18/MineScreen"; export default class MainComponent extends Component { render() { return ( <Navigator/> ); } }
const TabRouteConfigs = { Home: { screen: HomeScreen, tabBarComponent: TabBarTop, tabBarPosition: 'top', tabBarOptions: {} }; const Tab = TabNavigator(TabRouteConfigs,StackNavigatorConfigs);
|
DrawerNavigator
在原生Android MD 风格里面很多app都会采用侧滑抽屉来做主页面的导航,利用DrawerNavigator 在RN中可以很方便来实现抽屉导航。
1
|
DrawerNavigator(RouteConfigs,DrawerNavigatorConfig)
|
和DrawerNavigator 的构造函数一样,参数配置也类似。
RouteConfigs
抽屉导航的路由配置RouteConfigs ,和TabNavigator 的路由配置完全一样,screen 配置对应路由页面,navigationOptions 为对应页面的抽屉配置选项:
-
title - 抽屉标题,和headerTitle 、drawerLabel 一样
-
drawerLabel - 标签字符串,或者自定义组件, 可以根据{ focused: boolean,tintColor: string } 函数来返回一个自定义组件作为标签
-
drawerIcon - 抽屉icon,可以根据{ focused: boolean,tintColor: string } 函数来返回一个自定义组件作为icon
DrawerNavigatorConfig
抽屉配置项属性:
-
drawerWidth - 抽屉宽度,可以使用Dimensions获取屏幕的宽度,动态计算
-
drawerPosition - 抽屉位置,可以是left 或者right
-
contentComponent - 抽屉内容组件,可以自定义侧滑抽屉中的所有内容,默认为DrawerItems
-
contentOptions - 用来配置抽屉内容的属性。当用来配置DrawerItems 是配置属性选项:
-
items - 抽屉栏目的路由名称数组,可以被修改
-
activeItemKey - 当前选中页面的key id
-
activeTintColor - 选中条目状态的文字颜色
-
activeBackgroundColor - 选中条目的背景色
-
inactiveTintColor - 未选中条目状态的文字颜色
-
inactiveBackgroundColor - 未选中条目的背景色
-
onItemPress(route) - 条目按下时会调用此方法
-
style - 抽屉内容的样式
-
labelStyle - 抽屉的条目标题/标签样式
-
initialRouteName - 初始化展示的页面路由名称
-
order - 抽屉导航栏目顺序,用路由名称数组表示
-
paths - 路径
-
backBehavior - androd点击返回键时的处理,有initialRoute和none两个值,initailRoute :返回初始界面,none :退出
抽屉导航示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
import React,{Component} from 'react'; import {DrawerNavigator,StackNavigator,TabNavigator} from "react-navigation"; import HomeScreen from "./index18/HomeScreen"; import NearByScreen from "./index18/NearByScreen"; import MineScreen from "./index18/MineScreen"; import TabBarItem from "./index18/TabBarItem"; export default class MainComponent extends Component { render() { return ( <Navigator/> ); } } const DrawerRouteConfigs = { Home: { screen: HomeScreen, navigationOptions: ({navigation}) => ({ drawerLabel : '首页', drawerIcon : ({focused, navigationOptions: { drawerLabel : '附近', navigationOptions: { drawerLabel : '我的', } }; const DrawerNavigatorConfigs = { initialRouteName: 'Home', tabBarOptions: {} }; const Drawer = DrawerNavigator(DrawerRouteConfigs,DrawerNavigatorConfigs); const StackRouteConfigs = { Drawer: { screen: Drawer, } }; const StackNavigatorConfigs = { initialRouteName: 'Drawer',StackNavigatorConfigs);
|
源码:https://gitee.com/xiaojianjun/DD.git (index20.js、index21.js、index22.js)
参考
https://reactnavigation.org/docs/ ReactNative导航新宠儿react-navigation
原文:大专栏 ?React Native —— react-navigation的使用
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|