接触react-native
有一段时间了,感受学习最大的难点就是 rn的国内资料很少,老外写的文档看起来不舒服javascript
其中在react-navigation
上面花了很长的时间,搞的心力憔悴,可是看国内的文章,不少都是2.x版本的,api不向下兼容,各类报错对象不存在,前期每天踩坑html
后来看了很长时间的官方文档,才搞清楚react-navigation
的使用前端
因此在我感受我如今已经踩过不少坑的状况下,我决定写这篇文章,来帮助rn
开发者尽量的跳过react-navigation
的一些坑java
本人使用react-native的一些练习代码githubreact
react-native官网android
本文章基于 "react-navigation": "^3.0.9" 假如版本跨度比较大,本文可能就不适合了git
另外,学习库或者插件最好的方式就官方阅读文档(感受有点打脸本身)github
尽可能不要看百度出来的文章,,例如**dn,比较陈旧,已经不是个当前版本,必定要看文档web
rn项目里面,我推荐使用yarn, npm有时候会出现依赖不全的问题
在已经初始化完成,而且确保能够运行的rn项目里面,输入一下命令
yarn add react-navigation
yarn add react-native-gesture-handler
react-native link react-native-gesture-handler
复制代码
在已经搭建好的项目里面,运行上面的命令,这都是必须的,详情请看文档React navigation安装
安装完成后启动项目(启动无报错即意味着navigation安装成功了)
没有接触过原生开发的web开发者看到这些很react风格的导航器名称,必定很陌生,不要紧,后面图示
rn上的导航器的编写就是相似 前端的路由的编写,经过rn的导航器来决定App的路由结构,以及个性化的页面
createStackNavigator 最基本的页面 自带上方导航栏
为你的应用程序提供一种在每一个新屏幕放置在堆栈顶部的屏幕之间转换的方法。
createBottomTabNavigator
页面底部的标签栏,可以让您在不一样路由之间进行切换。 路由被懒加载 - 它们的屏幕组件只有在第一次获取焦点时才会被加载。
createMaterialBottomTabNavigator
功能上和 createBottomTabNavigator 同样,这个更加个性化,可是咱们能够基于createBottomTabNavigator
自定义任意底部导航栏
屏幕底部的材料设计主题标签栏,可以让您在不一样路由之间切换。 路由被懒加载 - 它们的屏幕组件直到第一次获取焦点时才被加载。
createMaterialTopTabNavigator
屏幕顶部左右滑动切换tab
屏幕顶部的材料设计主题标签栏, 可经过点击路线或水平滑动来切换不一样的路由。 默认状况下, 转换是动态的。 每一个路由的屏幕组件将当即安装。
createDrawerNavigator: 抽屉效果导航器,由侧边划出;
createSwitchNavigator:
createSwitchNavigator 的用途是一次只显示一个页面。 默认状况下,它不处理返回操做,并在你切换时将路由重置为默认状态。(特定场合才会使用)
经常使用的导航器就这么多,下面将一一介绍给你们
工欲善其事,必先利其器,好的开发环境能够有效地加速开发速度,以及开发体验感
使用vscode开发,推荐安装Full React/React Native/React Router/Redux/GraphQL/ES7/Testing/PropTypes snippets
另外开发react推荐插件
React Native Snippet
React Native Tools
Reactjs code snippets
以上插件安装完成后,就基本知足使用vscode进行react native的开发了 :wink:
安装好的项目咱们稍微改造一下,
one.js
two.js
three.js
是页面 随便写点什么就好
navigation
文件夹内部进行导航器的管理
这个是最多见的一个导航器,大部分页面都是经过他进行配置的,使用起来也很简单
先看看官方说明
如今咱们在navigation
/index.js
进行路由的配置
import { createStackNavigator, createAppContainer } from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const Stack = createStackNavigator({
One: {
screen: One
},
Two: {
screen: Two
},
Three: {
screen: Three
}
})
export default createAppContainer(Stack)
// createAppContainer是 react-navigation 的app容器,并将顶层的 navigator 连接到整个应用环境(后面再说)
复制代码
如今咱们须要在根节点导出这个导航器配置,因此须要修改根目录的App.js
import React, { Component } from 'react'
import Navigation from './app/navigation'
export default class App extends Component {
render() {
return <Navigation /> } } 复制代码
这个咱们就导出导航器配置,接下来重启项目
成功了!
可是目前还不能进行页面以前的切换,react-navigation
提供了导航器以前的切换功能
关于切换路由 react-navigation 提供了不少api,下图是最基础的一部分
还记得前面建立容器的API createAppContainer吗
他在props里面提供了navigation对象,用于进行导航器切换
在One.js里面添加切导航器的代码One.js
import React, { Component } from 'react'
import { Text, View, Button } from 'react-native'
export default class One extends Component {
render() {
return (
<View> <Text> One </Text> <Button title="跳转到Two页面" onPress={() => { this.props.navigation.navigate('Two') }} /> </View> ) } } 复制代码
原生的感受真的棒~
咱们不只能够切换页面,还能够像原生同样配置页面,react-navigation
提供了大量的导航的自定义配置
例如
咱们能够添加页面标题,ios与android,导航栏会自适应
咱们能够任意的选择显示或者不显示导航栏
设置导航栏颜色 等等你能够想到的个性化设置
更新naviigation
/index.js
import { createStackNavigator, createAppContainer } from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const Stack = createStackNavigator({
One: {
screen: One,
navigationOptions: {
title: 'One'
}
},
Two: {
screen: Two,
navigationOptions: {
title: 'Two',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
},
Three: {
screen: Three,
navigationOptions: {
title: 'Three'
}
}
},{
})
export default createAppContainer(Stack)
复制代码
更多的navigationOptions的配置请看官方文档的
大部分的移动端项目都有底部导航栏,得益于单页应用,webapp更多的出如今原生端那么在react-native上,如何建立一个底部导航栏呢?
从web的角度理解 就是 经过底部导航栏进行组件的懒加载切换
让咱们根据官方文档建立一个导航栏试试
修改navigation
/index.js
import {
createStackNavigator,
createBottomTabNavigator,
createAppContainer
} from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomBar = createBottomTabNavigator(
{
One: {
screen: One,
navigationOptions: {
title: 'One'
}
},
Two: {
screen: Two,
navigationOptions: {
title: 'Two'
}
},
Three: {
screen: Three,
navigationOptions: {
title: 'Three'
}
}
},
{
initialRouteName: 'One' // 初始化页面
}
)
const Stack = createStackNavigator({
BottomBar: {
screen: BottomBar,
navigationOptions: {
header: null
}
}
})
export default createAppContainer(Stack)
复制代码
咱们引入了createBottomTabNavigator
在createBottomTabNavigator
里面加了3个页面,最后将导出的底部导航器对象再加入到createStackNavigator
中,做为普通页面的形式
基础的底部导航器实现了~
在基础API上面,咱们能够作不少自定义的操做,自定义图标自定义文字,等等,具体请看文档
下面咱们给咱们的导航栏加一个图标,让他看起来更加美观
在项目里面添加几个小icon(图片用的是iconfont上面的)
网络上9成的文章都说明了在rn项目里面使用 react-native-vector-icons 这个图标库进行图标的添加 我这里使用不常见的方案,使用本地png图片做为底部icon,固然这个使用在具体项目里面应该封装起来,这样类小程序的模式,我相信能够很好的帮助理解,如下编码方式仅供学习
修改navigation
/index.js
import React from 'react'
import { Image } from 'react-native'
import {
createStackNavigator,
createBottomTabNavigator,
createAppContainer
} from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomBar = createBottomTabNavigator(
{
One: {
screen: One,
navigationOptions: {
title: 'One',
tabBarIcon: ({ tintColor }) => {
let sourceImg
if (tintColor == '#1296db') {
sourceImg = require('../image/one-active.png')
} else {
sourceImg = require('../image/one.png')
}
return (
<Image
source={sourceImg}
style={{ width: 24, height: 24 }}
color={tintColor}
/>
)}
}
},
Two: {
screen: Two,
navigationOptions: {
title: 'Two',
tabBarIcon: ({ tintColor }) => {
console.log(tintColor);
let sourceImg
if (tintColor == '#1296db') {
sourceImg = require('../image/my-active.png')
} else {
sourceImg = require('../image/my.png')
}
return (
<Image
source={sourceImg}
style={{ width: 24, height: 24 }}
color={tintColor}
/>
)}
}
},
Three: {
screen: Three,
navigationOptions: {
title: 'Three',
tabBarIcon: ({ tintColor }) => {
let sourceImg
if (tintColor == '#1296db') {
sourceImg = require('../image/message-active.png')
} else {
sourceImg = require('../image/message.png')
}
return (
<Image
source={sourceImg}
style={{ width: 24, height: 24 }}
color={tintColor}
/>
)}
}
}
},
{
initialRouteName: 'One', // 初始化页面
tabBarOptions: {
activeTintColor: '#1296db',
inactiveTintColor: 'black'
}
}
)
const Stack = createStackNavigator({
BottomBar: {
screen: BottomBar,
navigationOptions: {
header: null
}
}
})
export default createAppContainer(Stack)
复制代码
reactnavigation的导航栏只能作这些吗?固然不是,能够经过指定tabBarComponent
,来自定义你的导航栏组件,这个比较复杂,我后期会写一篇文章出来详细说明
这个给人一种开箱即用的感受,至于项目当中具体选择什么,这个要看需求
文档明确指出,须要安装如下库
yarn add react-navigation-material-bottom-tabs react-native-paper react-native-vector-icons
react-native link react-native-vector-icons
复制代码
咱们来实现一下官方案例的效果
修改navigation
/index.js
import React from 'react'
import {
createStackNavigator,
createAppContainer
} from 'react-navigation'
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'
import Ionicons from 'react-native-vector-icons/Ionicons'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomMater = createMaterialBottomTabNavigator(
{
One: {
screen: One,
navigationOptions: {
tabBarColor: '#3472EE', // 页面背景色
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-home" color={tintColor} size={24} />
)
}
},
Two: {
screen: Two,
navigationOptions: {
tabBarColor: '#EC3E3E',
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-options" color={tintColor} size={24} />
)
}
},
Three: {
screen: Three,
navigationOptions: {
tabBarColor: '#0EA748',
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-chatbubbles" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: 'One',
activeColor: 'white',
inactiveColor: 'gray',
shifting: true
}
)
const Stack = createStackNavigator({
BottomMater: {
screen: BottomMater,
navigationOptions: {
header: null
}
}
})
export default createAppContainer(Stack)
复制代码
这样相似的效果,react-navitation均可以完成,发挥你的想象力🤣
关于底部导航器的配置不少,没办法经过一篇文章一一介绍,详情请看官方文档
屏幕顶部的标签栏, 可经过点击路线或水平滑动来切换不一样的路由。 默认状况下, 转换是动态的。 每一个路由的屏幕组件将当即安装。
能够看一下我以前模拟拼多多的页面(当时是作技术验证)
就这样的效果
下面咱们能够根据文档在咱们的demo项目里面本身实现一下这样的效果
新增两个页面 Four.js
Five.js
随便写点什么就行
为了更加合理设置逻辑,我将TopBar的全部导航器配置代码放到一个文件当中
在navigation
文件夹内新建文件TopBar.js
import { createMaterialTopTabNavigator } from 'react-navigation'
import One from '../pages/One'
import Four from '../pages/Four'
import Five from '../pages/Five'
export default createMaterialTopTabNavigator(
{
One: {
screen: One, // 配置页面
navigationOptions: {
tabBarLabel: 'One'
}
},
Four: {
screen: Four,
navigationOptions: {
tabBarLabel: 'Four'
}
},
Five: {
screen: Five,
navigationOptions: {
tabBarLabel: 'Five'
}
}
},
{
initialRouteName: 'One',
lazy: true,
tabBarOptions: {
scrollEnabled: true,
upperCaseLabel: false, // 是否大写
activeTintColor: 'red', // 活动选项卡
inactiveTintColor: 'red', // "非活动" 选项卡
tabStyle: {
// 选项卡样式
// width: 60,
// paddingTop: 35,
paddingBottom: 4
},
style: {
backgroundColor: 'white' // 头部导航栏样式
},
indicatorStyle: {
backgroundColor: 'red' // 指示器样式
}
}
}
)
复制代码
最后修改navigation
/index.js
,将咱们新建的顶部导航器导入
import React from 'react'
import { Image } from 'react-native'
import {
createStackNavigator,
createBottomTabNavigator,
createAppContainer
} from 'react-navigation'
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'
import Ionicons from 'react-native-vector-icons/Ionicons'
import TopBar from './TopBar'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomMater = createMaterialBottomTabNavigator(
{
TopBar: {
screen: TopBar,
navigationOptions: {
tabBarColor: '#3472EE', // 页面背景色
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-home" color={tintColor} size={24} />
)
}
},
Two: {
screen: Two,
navigationOptions: {
tabBarColor: '#EC3E3E',
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-options" color={tintColor} size={24} />
)
}
},
Three: {
screen: Three,
navigationOptions: {
tabBarColor: '#0EA748',
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-chatbubbles" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: 'TopBar',
activeColor: 'white',
inactiveColor: 'gray',
shifting: true
}
)
const Stack = createStackNavigator({
BottomMater: {
screen: BottomMater,
navigationOptions: {
header: null
}
}
})
export default createAppContainer(Stack)
复制代码
是否是很简单,或者所,是否是学会了react-navigation的套路了 ~
到这里多联系,多理解,基本能够完成通常项目的搭建了,
你也能够看看我写过的其余文章,或者一些react-native的仓库代码,
定位 消息推送 APP启动屏 第三方集成 RN配置全面屏 都获得了比较好的解决
关于createDrawerNavigator
(抽屉组件) 和 createSwitchNavigator
(仅显示一次页面),放到后面再说~