React Native——react-navigation的使用

在 React Native 中,官方已經推薦使用 react-navigation 來實現各個界面的跳轉和不一樣板塊的切換。 react-navigation 主要包括三個組件:react

  • StackNavigator 導航組件
  • TabNavigator 切換組件
  • DrawerNavigator 抽屜組件

StackNavigator 用於實現各個頁面之間的跳轉, TabNavigator 用來實現同一個頁面上不一樣界面的切換, DrawerNavigator 能夠實現側滑的抽屜效果。android

StackNavigator

StackNavigator 組件採用堆棧式的頁面導航來實現各個界面跳轉。它的構造函數:git

StackNavigator(RouteConfigs, StackNavigatorConfig)

 

有 RouteConfigs 和 StackNavigatorConfig 兩個參數。api

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 爲對應路由的頁面。app

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 中屬性的優先級是:ui

頁面中靜態配置 > 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選項卡示例

import React, {Component} from "react";
import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
export default class MainComponent extends Component {
    render() {
        return (
            <Navigator/>
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: '首頁',
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: '附近',
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: '個人',
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: 'Home',
    tabBarComponent: TabBarTop,
    tabBarPosition: 'top',
    lazy: true,
    tabBarOptions: {}
};
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);

DrawerNavigator

在原生Android MD 風格里面不少app都會採用側滑抽屜來作主頁面的導航,利用 DrawerNavigator 在RN中能夠很方便來實現抽屜導航.

DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)

和 DrawerNavigator 的構造函數同樣,參數配置也相似。

RouteConfigs

抽屜導航的路由配置 RouteConfigs ,和 TabNavigator 的路由配置徹底同樣, screen 配置對應路由頁面, navigationOptions 爲對應頁面的抽屜配置選項:

  • title - 抽屜標題,和 headerTitle 、 drawerLabel 同樣
  • drawerLabel - 標籤字符串,或者自定義組件, 能夠根據 { focused: boolean, tintColor: string } 函數來返回一個自定義組件做爲標籤
  • drawerIcon - 抽屜icon,能夠根據 { focused: boolean, tintColor: string } 函數來返回一個自定義組件做爲icon

DrawerNavigatorConfig

抽屜配置項屬性:

drawerWidth - 抽屜寬度,可使用Dimensions獲取屏幕的寬度,動態計算
drawerPosition - 抽屜位置,能夠是 left 或者 right
contentComponent - 抽屜內容組件,能夠自定義側滑抽屜中的全部內容,默認爲 DrawerItems
contentOptions - 用來配置抽屜內容的屬性。當用來配置 DrawerItems 是配置屬性選項:
items - 抽屜欄目的路由名稱數組,能夠被修改
activeItemKey - 當前選中頁面的key id
activeTintColor - 選中條目狀態的文字顏色
activeBackgroundColor - 選中條目的背景色
inactiveTintColor - 未選中條目狀態的文字顏色
inactiveBackgroundColor - 未選中條目的背景色
onItemPress(route) - 條目按下時會調用此方法
style - 抽屜內容的樣式
labelStyle - 抽屜的條目標題/標籤樣式
initialRouteName - 初始化展現的頁面路由名稱
order - 抽屜導航欄目順序,用路由名稱數組表示
paths - 路徑
backBehavior - androd點擊返回鍵時的處理,有initialRoute和none兩個值, initailRoute:返回初始界面, none :退出

 

抽屜導航示例

import React, {Component} from 'react';
import {DrawerNavigator, 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 DrawerRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            drawerLabel : '首頁',
            drawerIcon : ({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: {
            drawerLabel : '附近',
            drawerIcon : ({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: {
            drawerLabel : '個人',
            drawerIcon : ({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 DrawerNavigatorConfigs = {
    initialRouteName: 'Home',
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    lazy: true,
    tabBarOptions: {}
};
const Drawer = DrawerNavigator(DrawerRouteConfigs, DrawerNavigatorConfigs);
const StackRouteConfigs = {
    Drawer: {
        screen: Drawer,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: 'Drawer',
    navigationOptions: {
        title: '標題',
        headerStyle: {backgroundColor: '#5da8ff'},
        headerTitleStyle: {color: '#333333'},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

源碼: https://git.oschina.net/xiaojianjun/DD (index20.js、index21.js、index22.js)

參考

相關文章
相關標籤/搜索