前言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徹底能勝任這個工做。
最後,核心代碼都在上面,我就不貼項目鏈接了。