1. 程式人生 > >React Native——react-navigation的使用

React Native——react-navigation的使用

在 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選項卡示例

  1. import React, {Component} from "react";
  2. import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
  3. import HomeScreen from "./index18/HomeScreen";
  4. import NearByScreen from "./index18/NearByScreen";
  5. import MineScreen from "./index18/MineScreen";
  6. export default classMainComponent