一塊兒來學習React-Native之react-navigation基本解析

前言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徹底能勝任這個工做。

 最後,核心代碼都在上面,我就不貼項目鏈接了。

相關文章
相關標籤/搜索