在 React Native 中,官方已经推荐使用 react-navigation 来实现各个界面的跳转和不同板块的切换。 react-navigation 主要包括三个组件:

  • StackNavigator 导航组件
  • TabNavigator 切换组件
  • DrawerNavigator 抽屉组件

StackNavigator 用于实现各个页面之间的跳转, TabNavigator 用来实现同一个页面上不同界面的切换, DrawerNavigator 可以实现侧滑的抽屉效果。

StackNavigator

StackNavigator 组件采用堆栈式的页面导航来实现各个界面跳转。它的构造函数:

StackNavigator(RouteConfigs, StackNavigatorConfig)

有 RouteConfigs 和 StackNavigatorConfig 两个参数。

RouteConfigs

RouteConfigs 参数表示各个页面路由配置,类似于android原生开发中的 AndroidManifest.xml ,它是让导航器知道需要导航的路由对应的页面。

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 参数表示导航器的配置,包括导航器的初始页面、各个页面之间导航的动画、页面的配置选项等等:

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 页面中:

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 ,直接引用该组件:

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可以看得到:

{
params: { param: 'i am the param' },
key: 'id-1500546317301-1',
routeName: 'Mine'
}

setParams

更改当前页面路由的参数,比如可以用来更新头部的按钮或者标题。

componentDidMount() {
this.props.navigation.setParams({param:'i am the new param'})
}

goBack

回退,可以不传,也可以传参数,还可以传 null 。

this.props.navigation.goBack();       // 回退到上一个页面
this.props.navigation.goBack(null); // 回退到任意一个页面
this.props.navigation.goBack('Home'); // 回退到Home页面

TabNavigator

TabNavigator ,即是Tab选项卡,类似于原生 android 中的 TabLayout ,它的构造函数:

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导航示例

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: '附近',
tabBarIcon: ({focused, 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: '我的',
tabBarIcon: ({focused, 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',
navigationOptions: {
title: '标题',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

顶部Tab选项卡示例

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,
navigationOptions: ({navigation}) => ({
tabBarLabel: '首页',
}),
},
NearBy: {
screen: NearByScreen,
navigationOptions: {
tabBarLabel: '附近',
},
}
,
Mine: {
screen: MineScreen,
navigationOptions: {
tabBarLabel: '我的',
},
}
};
const TabNavigatorConfigs = {
initialRouteName: 'Home',
tabBarComponent: TabBarTop,
tabBarPosition: 'top',
lazy: true,
tabBarOptions: {}
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
Tab: {
screen: Tab,
}
};
const StackNavigatorConfigs = {
initialRouteName: 'Tab',
navigationOptions: {
title: '标题',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

DrawerNavigator

在原生Android MD 风格里面很多app都会采用侧滑抽屉来做主页面的导航,利用 DrawerNavigator 在RN中可以很方便来实现抽屉导航.

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 :退出

抽屉导航示例

import React, {Component} from 'react';
import {DrawerNavigator, 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 DrawerRouteConfigs = {
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) => ({
drawerLabel : '首页',
drawerIcon : ({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: {
drawerLabel : '附近',
drawerIcon : ({focused, 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: {
drawerLabel : '我的',
drawerIcon : ({focused, 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 DrawerNavigatorConfigs = {
initialRouteName: 'Home',
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
lazy: true,
tabBarOptions: {}
};
const Drawer = DrawerNavigator(DrawerRouteConfigs, DrawerNavigatorConfigs);
const StackRouteConfigs = {
Drawer: {
screen: Drawer,
}
};
const StackNavigatorConfigs = {
initialRouteName: 'Drawer',
navigationOptions: {
title: '标题',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

源码: https://git.oschina.net/xiaojianjun/DD (index20.js、index21.js、index22.js)

参考

React Native——react-navigation的使用的更多相关文章

  1. React Navigation & React Native & React Native Navigation

    React Navigation & React Native & React Native Navigation React Navigation https://facebook. ...

  2. 如何用 React Native 创建一个iOS APP?(三)

    前两部分,<如何用 React Native 创建一个iOS APP?>,<如何用 React Native 创建一个iOS APP (二)?>中,我们分别讲了用 React ...

  3. H5、React Native、Native应用对比分析

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博!iOS开发者交流QQ群: 446310206 "存在即合理".凡是存在的,都是合乎规律的.任何新 ...

  4. H5、React Native、Native性能区别选择

    “存在即合理”.凡是存在的,都是合乎规律的.任何新事物的产生总要的它的道理:任何新事物的发展总是有着取代旧事物的能力.React Native来的正是时候,一则是因为H5发展到一定程度的受限:二则是移 ...

  5. React Native指南汇集了各类react-native学习资源、开源App和组件

    来自:https://github.com/ele828/react-native-guide React Native指南汇集了各类react-native学习资源.开源App和组件 React-N ...

  6. React Native纯干货总结

    随着项目也渐渐到了尾声,之前的项目是mobile开发,采用的是React Native.为即将要开始做RN项目或者已经做过的小伙伴可以参考借鉴,也顺便自己做一下之前项目的总结. 文章比较长,可以选择自 ...

  7. React Native at first sight

    what is React Native? 跟据官方的描述, React Native是一套使用 React 构建 Native app 的编程框架. 推出不久便引发了广泛关注, 这也得益于 Java ...

  8. React Native开发入门

    目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料   一.前言 虽然只是简单的了解了一下Reac ...

  9. React Native 简介:用 JavaScript 搭建 iOS 应用(2)

    [编者按]本篇文章的作者是 Joyce Echessa--渥合数位服务创办人,毕业于台湾大学,近年来专注于协助客户进行 App 软体以及网站开发.本篇文章中,作者介绍通过 React Native 框 ...

  10. React Native是一套使用 React 构建 Native app 的编程框架

    React Native是一套使用 React 构建 Native app 的编程框架 React Native at first sight what is React Native? 跟据官方的描 ...

随机推荐

  1. win10 家庭版不支持gpedit.msc的解决办法

    win10 家庭版不支持gpedit.msc的解决办法 1.建立一个批处理文件内容如下: @echo off pushd "%~dp0" dir /b %systemroot%\W ...

  2. 程序员利器Tmux使用手册

    转:https://blog.csdn.net/chenqiuge1984/article/details/80132042

  3. Windows 下安装drozer(Windows 10),连接手机(红米note4X)

    Windows 下安装drozer(Windows 10),连接手机(红米note4X) 首先下载drozer(http://mwr.to/drozer). 红米手机开发者模式 遇到第一个问题,红米手 ...

  4. sqlserver中批量导出所有作业或链接脚本

    问题描述: 经常在数据库迁移到另外一台服务器的时候,需要把作业也迁移过去,但是作业有时候好多个,要是一个个编写监本出来很麻烦 今天知道个简单方法批量可以导出sql脚本,顺便做个笔记 解决方法: 1.在 ...

  5. python + PyQt5 实现 简易计算器

    忽然想起之前一直想写个简单的计算器,今天就写了一下,界面有些简陋,但是基本功能实现没有问题 以下是源码: # --*-- coding:utf-8 --*-- import sys from PyQt ...

  6. LeetCode算法题-Reverse Words in a String III(Java实现)

    这是悦乐书的第259次更新,第272篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第126题(顺位题号是557).给定一个字符串,您需要反转句子中每个单词中的字符顺序,同 ...

  7. Docker: Harbor一些小知识

    镜像文件上传到私有仓库harbor后,镜像的物理存储位置在哪里? 这些信息记录在docker-compose.yml里,通过观察发现 镜像存储在了宿主机的 volumes: - /data/regis ...

  8. PhpStorm 常用插件

    PhpStorm 插件 Dash : Dash 需要配合软件 Dash 使用. IdeaVim IdeaVim 对于习惯于使用 Vim 操作方式的人来说是个大福音. IdeaVim 也有默认配置, 可 ...

  9. Django REST framework基础:序列化

    表结构: class Article(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(m ...

  10. java oop 集合框架

    集合主要是用来存放数据的,集合与数组的主要区别在于,集合的大小不受限制,而数组的大小受限制,在使用集合增加数据时又常常与泛型联系起来,所以集合和泛型在实际开发过程中总会结合在一起 数组致命的缺点是数组 ...