在React Native
中驼鹅,官方已經(jīng)推薦使用react-navigation
來實(shí)現(xiàn)各個(gè)界面的跳轉(zhuǎn)和不同板塊的切換抛计。react-navigation
主要包括三個(gè)組件:
-
StackNavigator
導(dǎo)航組件 -
TabNavigator
切換組件 -
DrawerNavigator
抽屜組件
StackNavigator
用于實(shí)現(xiàn)各個(gè)頁面之間的跳轉(zhuǎn)弄捕,TabNavigator
用來實(shí)現(xiàn)同一個(gè)頁面上不同界面的切換,DrawerNavigator
可以實(shí)現(xiàn)側(cè)滑的抽屜效果沟饥。
StackNavigator
StackNavigator
組件采用堆棧式的頁面導(dǎo)航來實(shí)現(xiàn)各個(gè)界面跳轉(zhuǎn)珠叔。它的構(gòu)造函數(shù):
StackNavigator(RouteConfigs, StackNavigatorConfig)
有RouteConfigs
和StackNavigatorConfig
兩個(gè)參數(shù)。
RouteConfigs
RouteConfigs
參數(shù)表示各個(gè)頁面路由配置虎眨,類似于android原生開發(fā)中的AndroidManifest.xml
蟋软,它是讓導(dǎo)航器知道需要導(dǎo)航的路由對(duì)應(yīng)的頁面。
const RouteConfigs = {
Home: {
screen: HomePage,
navigationOptions: ({navigation}) => ({
title: '首頁',
}),
},
Find: {
screen: FindPage,
navigationOptions: ({navigation}) => ({
title: '發(fā)現(xiàn)',
}),
},
Mine: {
screen: MinePage,
navigationOptions: ({navigation}) => ({
title: '我的',
}),
},
};
這里給導(dǎo)航器配置了三個(gè)頁面嗽桩,Home
岳守、Find
、Mine
為路由名稱碌冶,screen
屬性值HomePage
湿痢、FindPage
、MinePage
為對(duì)應(yīng)路由的頁面扑庞。
navigationOptions
為對(duì)應(yīng)路由頁面的配置選項(xiàng):
-
title
- 可以作為頭部標(biāo)題headerTitle
譬重,或者Tab標(biāo)題tabBarLabel
-
header
- 自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會(huì)消失 -
headerTitle
- 頭部的標(biāo)題罐氨,即頁面的標(biāo)題 -
headerBackTitle
- 返回標(biāo)題臀规,默認(rèn)為title
-
headerTruncatedBackTitle
- 返回標(biāo)題不能顯示時(shí)(比如返回標(biāo)題太長了)顯示此標(biāo)題,默認(rèn)為“Back”
-
headerRight
- 頭部右邊組件 -
headerLeft
- 頭部左邊組件 -
headerStyle
- 頭部組件的樣式 -
headerTitleStyle
- 頭部標(biāo)題的樣式 -
headerBackTitleStyle
- 頭部返回標(biāo)題的樣式 -
headerTintColor
- 頭部顏色 -
headerPressColorAndroid
-Android 5.0
以上MD風(fēng)格的波紋顏色 -
gesturesEnabled
- 否能側(cè)滑返回栅隐,iOS
默認(rèn)true
塔嬉,Android
默認(rèn)false
StackNavigatorConfig
StackNavigatorConfig
參數(shù)表示導(dǎo)航器的配置,包括導(dǎo)航器的初始頁面租悄、各個(gè)頁面之間導(dǎo)航的動(dòng)畫谨究、頁面的配置選項(xiàng)等等:
const StackNavigatorConfig = {
initialRouteName: 'Home',
initialRouteParams: {initPara: '初始頁面參數(shù)'},
navigationOptions: {
title: '標(biāo)題',
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('頁面跳轉(zhuǎn)動(dòng)畫開始');
}),
onTransitionEnd: (() => {
console.log('頁面跳轉(zhuǎn)動(dòng)畫結(jié)束');
}),
};
-
initialRouteName
- 導(dǎo)航器組件中初始顯示頁面的路由名稱,如果不設(shè)置泣棋,則默認(rèn)第一個(gè)路由頁面為初始顯示頁面 -
initialRouteParams
- 給初始路由的參數(shù)胶哲,在初始顯示的頁面中可以通過this.props.navigation.state.params
來獲取 -
navigationOptions
- 路由頁面的配置選項(xiàng),它會(huì)被RouteConfigs
參數(shù)中的navigationOptions
的對(duì)應(yīng)屬性覆蓋潭辈。 -
paths
- 路由中設(shè)置的路徑的覆蓋映射配置 -
mode
- 頁面跳轉(zhuǎn)方式纪吮,有card
和modal
兩種,默認(rèn)為card
:-
card
- 原生系統(tǒng)默認(rèn)的的跳轉(zhuǎn) -
modal
- 只針對(duì)iOS平臺(tái)萎胰,模態(tài)跳轉(zhuǎn)
-
-
headerMode
- 頁面跳轉(zhuǎn)時(shí)碾盟,頭部的動(dòng)畫模式,有float
技竟、screen
冰肴、none
三種:-
float
- 漸變,類似iOS的原生效果 -
screen
- 標(biāo)題與屏幕一起淡入淡出 -
none
- 沒有動(dòng)畫
-
-
cardStyle
- 為各個(gè)頁面設(shè)置統(tǒng)一的樣式,比如背景色熙尉,字體大小等 -
transitionConfig
- 配置頁面跳轉(zhuǎn)的動(dòng)畫联逻,覆蓋默認(rèn)的動(dòng)畫效果 -
onTransitionStart
- 頁面跳轉(zhuǎn)動(dòng)畫即將開始時(shí)調(diào)用 -
onTransitionEnd
- 頁面跳轉(zhuǎn)動(dòng)畫一旦完成會(huì)馬上調(diào)用
頁面的配置選項(xiàng)navigationOptions
通常還可以在對(duì)應(yīng)頁面中去靜態(tài)配置,比如在HomePage
頁面中:
export default class HomePage extends Component {
// 配置頁面導(dǎo)航選項(xiàng)
static navigationOptions = ({navigation}) => ({
title: 'HOME',
titleStyle: {color: '#ff00ff'},
headerStyle:{backgroundColor:'#000000'}
});
render() {
return (
<View></View>
)
};
}
同樣地检痰,在頁面里面采用靜態(tài)的方式配置navigationOptions
中的屬性包归,會(huì)覆蓋StackNavigator
構(gòu)造函數(shù)中兩個(gè)參數(shù)RouteConfigs
和StackNavigatorConfig
配置的navigationOptions
里面的對(duì)應(yīng)屬性。navigationOptions
中屬性的優(yōu)先級(jí)是:
頁面中靜態(tài)配置 > RouteConfigs
> StackNavigatorConfig
有了RouteConfigs
和StackNavigatorConfig
兩個(gè)參數(shù)铅歼,就可以構(gòu)造出一個(gè)導(dǎo)航器組件StackNavigator
公壤,直接引用該組件:
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig);
export default class MainComponent extends Component {
render() {
return (
<Navigator/>
)
};
}
已經(jīng)配置好導(dǎo)航器以及對(duì)應(yīng)的路由頁面了,但是要完成頁面之間的跳轉(zhuǎn)椎椰,還需要navigation
厦幅。
navigation
在導(dǎo)航器中的每一個(gè)頁面,都有navigation
屬性慨飘,該屬性有以下幾個(gè)屬性/方法:
-
navigate
- 跳轉(zhuǎn)到其他頁面 -
state
- 當(dāng)前頁面導(dǎo)航器的狀態(tài) -
setParams
- 更改路由的參數(shù) -
goBack
- 返回 -
dispatch
- 發(fā)送一個(gè)action
navigete
調(diào)用這個(gè)方法可以跳轉(zhuǎn)到導(dǎo)航器中的其他頁面确憨,此方法有三個(gè)參數(shù):
— routeName
導(dǎo)航器中配置的路由名稱
— params
傳遞參數(shù)到下一個(gè)頁面
— action
action
比如:this.props.navigation.navigate('Find', {param: 'i am the param'});
state
state
里面包含有傳遞過來的參數(shù)params
、key
瓤的、路由名稱routeName
休弃,打印log可以看得到:
{
params: { param: 'i am the param' },
key: 'id-1500546317301-1',
routeName: 'Mine'
}
setParams
更改當(dāng)前頁面路由的參數(shù),比如可以用來更新頭部的按鈕或者標(biāo)題圈膏。
componentDidMount() {
this.props.navigation.setParams({param:'i am the new param'})
}
goBack
回退塔猾,可以不傳,也可以傳參數(shù)本辐,還可以傳null
。
this.props.navigation.goBack(); // 回退到上一個(gè)頁面
this.props.navigation.goBack(null); // 回退到任意一個(gè)頁面
this.props.navigation.goBack('Home'); // 回退到Home頁面
TabNavigator
TabNavigator
医增,即是Tab選項(xiàng)卡慎皱,類似于原生android
中的TabLayout
,它的構(gòu)造函數(shù):
TabNavigator(RouteConfigs, TabNavigatorConfig)
api和StackNavigator
類似叶骨,參數(shù)RouteConfigs
是路由配置茫多,參數(shù)TabNavigatorConfig
是Tab選項(xiàng)卡配置。
RouteConfigs
路由配置和StackNavigator
中是一樣的忽刽,配置路由以及對(duì)應(yīng)的screen
頁面天揖,navigationOptions
為對(duì)應(yīng)路由頁面的配置選項(xiàng):
-
title
- Tab標(biāo)題,可用作headerTitle
和tabBarLabel
回退標(biāo)題 -
tabBarVisible
- Tab的是否可見跪帝,沒有設(shè)置的話默認(rèn)為true
-
tabBarIcon
- Tab的icon組件今膊,可以根據(jù){focused: boolean, tintColor: string}
方法來返回一個(gè)icon組件 -
tabBarLabel
- Tab中顯示的標(biāo)題字符串或者組件,也可以根據(jù){ focused: boolean, tintColor: string }
方法返回一個(gè)組件
TabNavigatorConfig
-
tabBarComponent
- Tab選項(xiàng)卡組件伞剑,有TabBarBottom
和TabBarTop
兩個(gè)值斑唬,在iOS中默認(rèn)為TabBarBottom
,在Android中默認(rèn)為TabBarTop
。-
TabBarTop
- 在頁面的頂部 -
TabBarBottom
- 在頁面的底部
-
-
tabBarPosition
- Tab選項(xiàng)卡的位置恕刘,有top
或bottom
兩個(gè)值 -
swipeEnabled
- 是否可以滑動(dòng)切換Tab選項(xiàng)卡 -
animationEnabled
- 點(diǎn)擊Tab選項(xiàng)卡切換界面是否需要?jiǎng)赢?/li> -
lazy
- 是否懶加載頁面 -
initialRouteName
- 初始顯示的Tab對(duì)應(yīng)的頁面路由名稱 -
order
- 用路由名稱數(shù)組來表示Tab選項(xiàng)卡的順序缤谎,默認(rèn)為路由配置順序 -
paths
- 路徑配置 -
backBehavior
- androd點(diǎn)擊返回鍵時(shí)的處理,有initialRoute
和none
兩個(gè)值-
initailRoute
- 返回初始界面 -
none
- 退出
-
-
tabBarOptions
- Tab配置屬性褐着,用在TabBarTop
和TabBarBottom
時(shí)有些屬性不一致:- 用于
TabBarTop
時(shí):-
activeTintColor
- 選中的文字顏色 -
inactiveTintColor
- 未選中的文字顏色 -
showIcon
- 是否顯示圖標(biāo)坷澡,默認(rèn)顯示 -
showLabel
- 是否顯示標(biāo)簽,默認(rèn)顯示 -
upperCaseLabel
- 是否使用大寫字母含蓉,默認(rèn)使用 -
pressColor
- android 5.0以上的MD風(fēng)格波紋顏色 -
pressOpacity
- android 5.0以下或者iOS按下的透明度 -
scrollEnabled
- 是否可以滾動(dòng) -
tabStyle
- 單個(gè)Tab的樣式 -
indicatorStyle
- 指示器的樣式 -
labelStyle
- 標(biāo)簽的樣式 -
iconStyle
- icon的樣式 -
style
- 整個(gè)TabBar的樣式
-
- 用于
- 用于
TabBarBottom
時(shí):-
activeTintColor
- 選中Tab的文字顏色 -
activeBackgroundColor
- 選中Tab的背景顏色 -
inactiveTintColor
- 未選中Tab的的文字顏色 -
inactiveBackgroundColor
- 未選中Tab的背景顏色 -
showLabel
- 是否顯示標(biāo)題频敛,默認(rèn)顯示 -
style
- 整個(gè)TabBar的樣式 -
labelStyle
- 標(biāo)簽的樣式 -
tabStyle
- 單個(gè)Tab的樣式
-
底部Tab導(dǎo)航示例
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: '標(biāo)題',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
頂部Tab選項(xiàng)卡示例
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: '標(biāo)題',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
DrawerNavigator
在原生Android MD 風(fēng)格里面很多app都會(huì)采用側(cè)滑抽屜來做主頁面的導(dǎo)航,利用DrawerNavigator
在RN中可以很方便來實(shí)現(xiàn)抽屜導(dǎo)航谴餐。
DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
和DrawerNavigator
的構(gòu)造函數(shù)一樣姻政,參數(shù)配置也類似。
RouteConfigs
抽屜導(dǎo)航的路由配置RouteConfigs
岂嗓,和TabNavigator
的路由配置完全一樣汁展,screen
配置對(duì)應(yīng)路由頁面,navigationOptions
為對(duì)應(yīng)頁面的抽屜配置選項(xiàng):
-
title
- 抽屜標(biāo)題厌殉,和headerTitle
食绿、drawerLabel
一樣 -
drawerLabel
- 標(biāo)簽字符串,或者自定義組件公罕, 可以根據(jù){ focused: boolean, tintColor: string }
函數(shù)來返回一個(gè)自定義組件作為標(biāo)簽 -
drawerIcon
- 抽屜icon器紧,可以根據(jù){ focused: boolean, tintColor: string }
函數(shù)來返回一個(gè)自定義組件作為icon
DrawerNavigatorConfig
抽屜配置項(xiàng)屬性:
-
drawerWidth
- 抽屜寬度,可以使用Dimensions獲取屏幕的寬度楼眷,動(dòng)態(tài)計(jì)算 -
drawerPosition
- 抽屜位置铲汪,可以是left
或者right
-
contentComponent
- 抽屜內(nèi)容組件,可以自定義側(cè)滑抽屜中的所有內(nèi)容罐柳,默認(rèn)為DrawerItems
-
contentOptions
- 用來配置抽屜內(nèi)容的屬性掌腰。當(dāng)用來配置DrawerItems
是配置屬性選項(xiàng):-
items
- 抽屜欄目的路由名稱數(shù)組,可以被修改 -
activeItemKey
- 當(dāng)前選中頁面的key id -
activeTintColor
- 選中條目狀態(tài)的文字顏色 -
activeBackgroundColor
- 選中條目的背景色 -
inactiveTintColor
- 未選中條目狀態(tài)的文字顏色 -
inactiveBackgroundColor
- 未選中條目的背景色 -
onItemPress(route)
- 條目按下時(shí)會(huì)調(diào)用此方法 -
style
- 抽屜內(nèi)容的樣式 -
labelStyle
- 抽屜的條目標(biāo)題/標(biāo)簽樣式
-
-
initialRouteName
- 初始化展示的頁面路由名稱 -
order
- 抽屜導(dǎo)航欄目順序张吉,用路由名稱數(shù)組表示 -
paths
- 路徑 -
backBehavior
- androd點(diǎn)擊返回鍵時(shí)的處理齿梁,有initialRoute和none兩個(gè)值,initailRoute
:返回初始界面肮蛹,none
:退出
抽屜導(dǎo)航示例
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: '標(biāo)題',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
源碼:https://gitee.com/xiaojianjun/DD.git (index20.js勺择、index21.js、index22.js)
參考
https://reactnavigation.org/docs/
ReactNative導(dǎo)航新寵兒react-navigation