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

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)

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM