前言html
不久前本身也完整开发了一个React-Native项目,对其中的一些知识存在疑惑,再加上项目时间比较紧张,来不及作系统的学习。如今来回顾本身开发当中存在的疑惑点,和你们分享。第一篇是关于路由框架react-navigation,当时其实也没有好好看文档,如今回头看路由设计的确实比较乱,若是没看过文档建议直接去看文档,然后再看此篇文章。主要介绍createStackNavigator,createSwitchNavigator,createBottomTabNavigator,createMaterialTopTabNavigator,这四类路由框架,以及他们的组合使用。react
createStackNavigatorreact-native
顾名思义,其实这就是一种基于栈的路由管理方式,栈的特色就是先入后出,最新入栈的界面会显示在最顶部,这也是Android管理Activity的方式,也是React-Native App打开页面最主要的方式。
微信
export function createStackNavigator( routeConfigMap: NavigationRouteConfigMap, stackConfig?: StackNavigatorConfig ): NavigationContainer;
该方法提供两个参数,一个是NavigationRouteConfigMap,当中存储的一些你声明的组件,他们之间构成了一个单独的路由。还有一个参数是StackNavigatorConfig,它容许你对路由作一个全局的设置,好比说是否显示头部,头部的主题等等。这边建议都不显示头部,更多的时候,页面的头部不尽相同,经过自定的这种形式会对开发更加的友好。须要注意的是,在最新版本的react-navigation当中,必须经过createAppContainer包裹导出。经过建立js文件:AppNavigator.js,一个完整的基于createStackNavigator的例子以下:app
import { createStackNavigator, createSwitchNavigator, createAppContainer, createBottomTabNavigator, createMaterialTopTabNavigator } from 'react-navigation' import SplashPage from "../page/Splash/SplashPage"; import HomePage from "../page/Home/HomePage"; import Feather from "react-native-vector-icons/Feather" import Page1 from "../page/bottom/Page1"; import Page2 from "../page/bottom/Page2"; import Page3 from "../page/bottom/Page3"; import React from "react"; import Top1 from "../page/top/Top1"; import Top2 from "../page/top/Top2"; import Top3 from "../page/top/Top3"; const InitNavigator = createStackNavigator({ SplashPage: { screen: SplashPage, navigationOptions: { header: null } }, Page1: { screen: Page1, navigationOptions: { header: null } }, Page2: { screen: Page2, navigationOptions: { header: null } }, Page3: { screen: Page3, navigationOptions: { header: null } }, },{ }); export default createAppContainer(InitNavigator);
这个时候咱们只须要修改App.js,就能够完成接入路由这个操做了。框架
import React, {Component} from 'react'; import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native'; import AppNavigator from "./app/navigation/AppNavigator"; type Props = {}; export default class App extends Component<Props> { render() { return ( <AppNavigator/> ); } }
能够看到,单个js文件中的路由以单个组件的形式提供,能够预见,在项目路由复杂,项目路由多这种状况下react-navigation也同样能够轻松的管理路由。具体的页面代码就再也不展现,效果以下:学习
createSwitchNavigatorflex
switch,意思也比较明显,就是选择的意思。也就是说,当你使用这个路由时,内存中只会存在一个页面或者一个路由(多路由状况)。其实,大多数App都有一个欢迎界面,这个界面在App中只会显示一次,若是单单是使用栈的形式,很差控制出栈的操做,实现起来就比较复杂,那么咱们的createSwitchNavigator就能派上用场了。当跳转到咱们的主路由的时候,欢迎界面也就消失了。来看一下createSwitchNavigator中提供的参数:this
export function createSwitchNavigator( routeConfigMap: NavigationRouteConfigMap, switchConfig?: SwitchNavigatorConfig ): NavigationContainer;
能够看到和createStackNavigator大同小意,也是一个路由管理集合,和一个能够对界面的整体设置,那么要实现咱们上面想要的效果如何去作呢?其实也很是简单,代码以下:spa
import { createStackNavigator, createSwitchNavigator, createAppContainer, createBottomTabNavigator, createMaterialTopTabNavigator } from 'react-navigation' import SplashPage from "../page/Splash/SplashPage"; import HomePage from "../page/Home/HomePage"; import Feather from "react-native-vector-icons/Feather" import Page1 from "../page/bottom/Page1"; import Page2 from "../page/bottom/Page2"; import Page3 from "../page/bottom/Page3"; import React from "react"; import Top1 from "../page/top/Top1"; import Top2 from "../page/top/Top2"; import Top3 from "../page/top/Top3"; const InitNavigator = createStackNavigator({ Page1: { screen: Page1, navigationOptions: { header: null } }, Page2: { screen: Page2, navigationOptions: { header: null } }, Page3: { screen: Page3, navigationOptions: { header: null } }, },{ }); const AppRoot = createSwitchNavigator({ SplashPage: { screen: SplashPage, navigationOptions: { header: null } }, Main: InitNavigator, }); export default createAppContainer(AppRoot);
那么这个时候,咱们的splash界面就再也不是跳转到page1了。而是在AppRoot中的Main了。
import BasePage from "../../base/BasePage"; import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native'; import React, {Component} from 'react'; export default class SplashPage extends BasePage { render() { return ( <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <TouchableOpacity onPress={() => { this.goNextPage("Main") }}> <Text>Splash</Text> </TouchableOpacity> </View> ); } }
如今来看下效果
createBottomTabNavigator
若是咱们要实现相似微信首页多tab多界面的时候,createBottomTabNavigator就能派上用场了,他经过单个路由管理多个tab,咱们来看一下实现的参数:
export function createBottomTabNavigator( routeConfigMap: NavigationRouteConfigMap, drawConfig?: BottomTabNavigatorConfig ): NavigationContainer;
哎呀,和前面两个同样,也是一个路由管理集合,和一个能够对界面的整体设置。具体设置属性的参数这里很少说,之后的文章会说到,咱们把上面提到的两个路由结合起来,实现一个大部分App都有的一个正常路由流程。外部是个createSwitchNavigator作splash和主路由,主路由经过createStackNavigator用栈管理,可是第一个page咱们使用createBottomTabNavigator作首页。那么代码以下:
import { createStackNavigator, createSwitchNavigator, createAppContainer, createBottomTabNavigator, createMaterialTopTabNavigator } from 'react-navigation' import SplashPage from "../page/Splash/SplashPage"; import HomePage from "../page/Home/HomePage"; import Feather from "react-native-vector-icons/Feather" import Page1 from "../page/bottom/Page1"; import Page2 from "../page/bottom/Page2"; import Page3 from "../page/bottom/Page3"; import React from "react"; import Top1 from "../page/top/Top1"; import Top2 from "../page/top/Top2"; import Top3 from "../page/top/Top3"; let hotSelest = <Feather name={'activity'} size={26} color='red' />; let hotUnSelest = <Feather name={'activity'} size={26} />; let pointSelect = <Feather name={'thumbs-up'} size={26} color='red' />; let pointUnSelect = <Feather name={'thumbs-up'} size={26} />; let mineSelect = <Feather name={'user'} size={26} color='red' />; let mineUnSelect = <Feather name={'user'} size={26} />; const BottomNavigator = createBottomTabNavigator({ Page1: { screen: Page1, navigationOptions: { tabBarLabel: '最热', tabBarIcon: ({tinColor, focused}) => (focused ? hotSelest : hotUnSelest) } }, Page2: { screen: Page2, navigationOptions: { tabBarLabel: '点赞', tabBarIcon: ({tinColor, focused}) => (focused ? pointSelect : pointUnSelect) } }, Page3: { screen: Page3, navigationOptions: { tabBarLabel: '个人', tabBarIcon: ({tinColor, focused}) => (focused ? mineSelect : mineUnSelect) } }, }, { tabBarOptions: { activeTintColor: '#e91e63', header: null, } }); const InitNavigator = createStackNavigator({ Page1: { screen: BottomNavigator, navigationOptions: { header: null } }, Top1: { screen: Top1, navigationOptions: { header: null } }, Top2: { screen: Top2, navigationOptions: { header: null } }, },{ }); const AppRoot = createSwitchNavigator({ SplashPage: { screen: SplashPage, navigationOptions: { header: null } }, Main: InitNavigator, }); export default createAppContainer(AppRoot);
经过设置lable,icon两个属性,设置图片和文字,这边没有图片,因此使用了一个三方库,有兴趣的能够了解一下。你也能够在,全局的设置当中设置是否显示lable和icon和文字选中颜色等等。首页的第一个界面点击以后会跳转到top界面,效果以下:
createMaterialTopTabNavigator
同过实现一个material风格的顶部选择导航,相对于createBottomTabNavigator,有些属性不一样。咱们来看看实现方法:
export function createMaterialTopTabNavigator( routeConfigMap: NavigationRouteConfigMap, drawConfig?: TabNavigatorConfig ): NavigationContainer;
也是大同小异,具体的属性差异实践以后体会更加深入,我也会在后面介绍,包括一下高级的用法。咱们让首页第一个变成materialtop的风格,代码也是很是简单,咱们在上面的基础上修改一下:
import { createStackNavigator, createSwitchNavigator, createAppContainer, createBottomTabNavigator, createMaterialTopTabNavigator } from 'react-navigation' import SplashPage from "../page/Splash/SplashPage"; import HomePage from "../page/Home/HomePage"; import Feather from "react-native-vector-icons/Feather" import Page1 from "../page/bottom/Page1"; import Page2 from "../page/bottom/Page2"; import Page3 from "../page/bottom/Page3"; import React from "react"; import Top1 from "../page/top/Top1"; import Top2 from "../page/top/Top2"; import Top3 from "../page/top/Top3"; const TopNavigator= createMaterialTopTabNavigator({ TopOne:{ screen:Top1 }, TopTwo:{ screen:Top2 }, TopThree:{ screen:Top3 }, }); let hotSelest = <Feather name={'activity'} size={26} color='red' />; let hotUnSelest = <Feather name={'activity'} size={26} />; let pointSelect = <Feather name={'thumbs-up'} size={26} color='red' />; let pointUnSelect = <Feather name={'thumbs-up'} size={26} />; let mineSelect = <Feather name={'user'} size={26} color='red' />; let mineUnSelect = <Feather name={'user'} size={26} />; const BottomNavigator = createBottomTabNavigator({ Page1: { screen: TopNavigator, navigationOptions: { tabBarLabel: '最热', tabBarIcon: ({tinColor, focused}) => (focused ? hotSelest : hotUnSelest) } }, Page2: { screen: Page2, navigationOptions: { tabBarLabel: '点赞', tabBarIcon: ({tinColor, focused}) => (focused ? pointSelect : pointUnSelect) } }, Page3: { screen: Page3, navigationOptions: { tabBarLabel: '个人', tabBarIcon: ({tinColor, focused}) => (focused ? mineSelect : mineUnSelect) } }, }, { tabBarOptions: { activeTintColor: '#e91e63', header: null, } }); const InitNavigator = createStackNavigator({ Page1: { screen: BottomNavigator, navigationOptions: { header: null } }, Top1: { screen: Top1, navigationOptions: { header: null } }, Top2: { screen: Top2, navigationOptions: { header: null } }, },{ }); const AppRoot = createSwitchNavigator({ SplashPage: { screen: SplashPage, navigationOptions: { header: null } }, Main: InitNavigator, }); export default createAppContainer(AppRoot);
在createBottomTabNavigator的第一个界面,加入了materialtop的路由,来看看效果:
总结
来作一个简单的总结:
1.这几种路由无非就是两个参数,一个是界面的集合以及全局界面属性的设置,不一样的路由属性不一样,你也能够在单个界面设置他的属性。
2.路由的使用须要经过createAppContainer包裹,他以一个组件的形式体如今咱们的界面上,这也是新版本加上的,无疑让他更加的灵活。
3.一个完整的App路由绝对不是单个路由那么简单的,要好好思考App的业务逻辑,设置出专属于你的路由,react-navigation彻底能胜任这个工做。
最后,核心代码都在上面,我就不贴项目链接了。