此文項目代碼:https://github.com/bei-yang/I-want-to-be-an-architect
碼字不易,辛苦點個star,感謝!
引言
此篇文章主要涉及以下內容:
- react navigation3.x的安裝流程
- react navigation 相關屬性,和API
- createStackNavigator普通導航使用
- 使用react-native-vector-icons圖標庫
react navigation介紹
源于React Native社區對基于Javascript的可擴展且使用簡單的導航解決方案的需求
react-natvigation自開源以來。在短短不到3個月的時間,github上星數已達4000+。Fb推薦使用庫,并且在React Native當前最新版本0.44中將Navigator刪除。react-navigation據稱有原生般的性能體驗效果。可能會成為未來React Native導航組件的主流軍
安裝
https://reactnavigation.org/docs/zh-Hans/getting-started.html
導航器
導航器也可以看成是一個普通的React組件,你可以通過導航器來定義你的APP中的導航結構。導航器還可以渲染通用元素,例如可以配置的標題欄和選項卡欄。
在react-navigation中有以下類型的導航器:
- createStackNavigator:類似普通的Navigator,導航上方導航欄
- createTabNavigator:已棄用,使用createBottomTabNavigator、createMaterialTopTabNavigator替代
- createBottomTabNavigator:相當于IOS里面的UITabBarController,屏幕下方的標簽欄
- createMaterialTopTabNavigator:屏幕頂部的材料設計主題標簽欄
- createDrawerNavigator:抽屜效果,側邊滑出
- createSwitchNavigator:SwitchNavigator的用途是一次只顯示一個頁面
你可以通過以上幾種導航器來創建你的APP,可以是其中一個也可以多個組合,這個可以根據具體的應用場景并結合每一個導航器的特性進行選擇。
相關概念
在開始學習導航器之前,我們需要了解兩個和導航有關的概念:
- Screen navigation prop(屏幕導航屬性):通過navigation可以完成屏幕之間的調度操作,例如打開另一個屏幕
- Screen navigationOptions(屏幕導航選項):通過navigationOptions可以定制導航器顯示屏幕的方式(例如:頭部標題,選項卡標簽等)
導航器所支持的Props
const SomeNav = createStackNavigator/createBottomTabNavigator/createMaterialTopTabNavigator({
// config
});
<SomeNav
screenProps = {xxx} //向子屏幕傳遞額外的數據,子屏幕可以通過this.props.screenProps獲取到該數據
ref = {nav => {navigation = nav;}} //可以通過ref屬性獲取到navigation;
onNavigationStateChange=(prevState,newState,action)=>{
//onNavigationStateChange:每次當導航器所管理的state發生改變時,都會回調該方法
//prevState:變化之前的state
//newState:新的state
//action:導致state變化的action
}
/>
Screen Navigation Prop(屏幕的navigation props)
當導航器中的屏幕被打開時,它會接收到一個navigation prop,它是整個導航環節的關鍵一員,接下來詳細的講解一下navigation prop的作用
navigation:包含以下功能
- navigate:跳轉到其他界面
- state:屏幕的當前state
- setParams:改變路由的params
- goBack:關閉當前屏幕
- disPatch:向路由發送一個action
- addListener:訂閱導航生命周期的更新
- isFocused:true標識屏幕獲取了焦點
- getParam:獲取具有回退的特定參數
- dangerouslyGetParent:返回父導航器
注意:一個navigation有可能沒有navigate、setParams以及goBack,只有state與dispatch,所以在使用navigate時要進行判斷,如果沒有navigate可以使用navigation去dispatch一個新的action。如:
const {navigation,theme,selectedTab} = this.props;
const resetAction = StackActions.reset({
index:0,
action:[
NavigationActions.navigate({
routeName: 'HomePage',
params:{
theme:theme,
selectedTab:selectedTab
}
})
]
})
navigation.dispatch(resetAction)
提示:這里的reset在2.0及以后的版本中,從NavigationActions中移到了StackActions中了,使用時記得留意。
StackNavigator的navigation的額外功能:
當且僅當當前navigator是stackNavigator時,this.props.navigation上有一些附加功能。這些函數是navigate和goBack的替代方法,你可以使用任何你喜歡的方法。這些功能是:
- this.props.navigation
- Push :導航到堆棧中的一個新路由
- pop:返回堆棧中的上一個頁面
- popToTop:跳轉到堆棧中最頂層的頁面
- replace:用新路由替換當前路由
- reset:擦除導航器狀態并將其替換為多個操作的結果
- dismiss:關閉當前棧
使用navigate進行界面之間的跳轉
- navigation.navigate({routeName,params,action,key})或者navigation.navigate(routeName,params,action)
- routeName:要跳轉到的界面路由名稱,也就是導航其中配置的路由名
- params:要傳遞給下一個界面的參數
- action:如果該界面是一個navigator的話,將運行這個sub-action
- Key:要導航到的路由的可選標識符,如果已存在,將后退到此路由
export const AppStackNavigator = createStackNavigator({
HomeScreen: {
screen: HomeScreen
},
Page1: {
screen: Page1
}
})
class HomeScreen extends React.Component {
render(){
const {navigate} = this.props.navigation;
return (
<View>
<Text>This is HomeScreen</Text>
<Button
onPress={()=> navigate('Page1',{
name: 'David'
})}
title = "Go to Page1"
/>
</View>
)
}
}
使用state的params
可以通過this.props.state.params來獲取通過setParams(),或navigation.navigate()傳遞的參數。
<Button
title={params.mode === 'edit' ? '保存' : '編輯'}
onPress={()=>
setParams({
mode: params.mode === 'edit'? '' : 'edit'
})
}
/>
<Button
title="Go to Page1"
onPress={()=>{
navigation.navigate('Page1',{name:'David'})
}}
/>
const {navigation} = this.props
const {state,setParams} = navigation
const {params} = state
const showText = params.mode === 'edit'? '正在編輯':'編輯完成'
使用setParams改變route Params
- setParams:function setParams(params):可以借助setParams來改變route Params,比如,通過setParams來更新頁面頂部的標題,返回按鈕等
class ProfileScreen extends React.Component {
render(){
const {setParams} = this.props.navigation
return(
<Button
onPress={()=>setParams({name: 'Lucy'})}
title="set title name to 'Lucy'"
/>
)
}
}
注意navigation.setParams改變的是當前頁面的Params,如果要改變其他頁面的Params可以通過NavigationActions.setParams完成,下文會講到
使用goBack返回上一頁面或指定頁面
- goBack:function goBack(key):我們可以借助goBack返回到上一頁或者路由棧的指定頁面。
- 之中key標識你要返回到頁面的頁面標識符,如:id-1517035332238-4,不是routeName
- 可以通過指定頁面的navigation.state.key來獲取頁面的標識
- key非必傳,也可傳null
navigation.state {params: {…},key:"id-1517035332238-4",routeName:"Page1"}
export default class Page1 extends React.ComPonent {
render(){
const {navigation} = this.props;
return <View>
<Text>歡迎來到Page1</Text>
<Button
title="Go Back"
onPress={()=>{
navigation.goBack()
}}
/>
</View>
}
}
通過dispatch 發送一個action
- dispatch:function dispatch(action):給當前界面設置action,會替換原來的跳轉,回退等事件
const resetAction = StackActions.reset({
index:0,
actions:[
NavigationActions.navigate({
routeName: 'HomePage',
params:{
theme:theme,
selectedTab:selectedTab
}
})
]
})
navigation.dispatch(resetAction)
NavigationActions
- Navigate:導航到其他頁面
- Back:返回到上一個頁面
- Set Params:設置指定頁面的Params
- Init:初始化一個state,如果state是undefined
Navigate
navigate action 會使用 navigate action的結果來更新當前的state
navigate({routeName,params,action,key})
- routeName: 字符串,必選項,在app的router里注冊的導航目的地的routeName
- params:對象,可選項,融合進目的地route的參數
- actions:對象,可選項(高級),如果screen也是一個navigator,次級action可以在子route中運行,在文檔中描述的任何actions都可以作為次級action.
- key:string or null 可選,要導航到的路由的標識符,如果已存在,則導航回此路由
import {NavigationActions} from 'react-navigation'
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({
routeName: 'SubProfileRoute'
})
})
this.props.navigation.dispatch(navigationAction)
Back
返回到前一個screen并且關閉當前screen.backaction creator 接受一個可選的參數:
back(key)
- Key String可選,這個可以和上文中講到的goBack的key是一個概念;
import { NavigationActions } from 'react-navigation'
const backAction = NavigationActions.back();
this.props.navigation.dispacth(backAction)
SetParams
通過SetParams我們可以修改指定頁面的Params
- Params:對象,必選參數,將會被合并到已經存在頁面的Params中
- key:字符串,必選參數,頁面的key
import {NavigationActions} from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
params:{title:'HomePage'},
key:'id-1517035332238-4'
})
有很多小伙伴可能會問:navigation中有setParams為什么還要有NavigationActions.setParams?
從兩方面來回答一下這個問題:
- 在上文中講到過navigation中有可能只有stata和dispatch,這個時候如果要修改頁面的Params,則只能通過NavigationActions.setParams了
- 另外,navigation.setParams只能修改當前頁面的params,而navigationActions.setParams可以修改所有頁面的Params
StackActions
- Reset:重置當前state到一個新的state
- replace:使用另一個路由替換指定的路由
- Push:在堆棧頂部添加一個頁面,然后跳轉到該頁面
- Pop:跳轉到上一個頁面
- PopToTop:跳轉到堆棧最頂層的頁面,并銷毀其他所有頁面
Reset
Reset action刪掉所有的navigation state并且使用這個actions的結果來代替
- index:數組,必選,navigation state中route數組中激活route的index
- actions:數組,必選,navigation actions數組,將會替代navigation state
- key:string or null 可選,如果設置,具有給定key的導航器將重置。如果為null,則根導航器將重置。
createStackNavigator-普通導航 堆棧
createStackNavigator
提供APP屏幕之間切換的能力,它是以棧的形式還管理屏幕之間的切換,新切換到的屏幕會放在棧的頂部。
createStackNavigator API
createStackNavigator(RouteConfigs, StackNavigatorConfig):
-
RouteConfigs
(必選):路由配置對象是從路由名稱到路由配置的映射,告訴導航器該路由呈現什么。 -
StackNavigatorConfig
(可選):配置導航器的路由(如:默認首屏,navigationOptions,paths等)樣式(如,轉場模式mode、頭部模式等)。
RouteConfigs
RouteConfigs支持三個參數screen
、path
以及navigationOptions
;
-
screen
(必選):指定一個 React 組件作為屏幕的主要顯示內容,當這個組件被createStackNavigator加載時,它會被分配一個navigation
prop。 -
path
(可選):用來設置支持schema跳轉時使用,具體使用會在下文的有關Schema
章節中講到; -
navigationOptions
(可選):用以配置全局的屏幕導航選項如:title、headerRight、headerLeft等;
StackNavigatorConfig
從react-navigation
源碼中可以看出StackNavigatorConfig支持配置的參數有10個。
function createStackNavigator(routeConfigMap, stackConfig = {}) {
const {
initialRouteKey,
initialRouteName,
initialRouteParams,
paths,
defaultNavigationOptions,
disableKeyboardHandling,
getCustomActionCreators
} = stackConfig;
...
這7個參數可以根據作用不同分為路由配置、視圖樣式配置兩類,首先看用于路由配置的參數:
用于路由配置的參數:
- initialRouteName: 設置默認的頁面組件,必須是上面已注冊的頁面組件。
- initialRouteParams: 初始路由的參數。
- defaultNavigationOptions: 屏幕導航的默認選項,下文會詳細講解。
- initialRouteKey - 初始路由的可選標識符。
- paths: 用來設置支持schema跳轉時使用,具體使用會在下文的有關
Schema
章節中講到。
用于導航樣式配置的參數:
- mode: 頁面切換模式: 左右是card(相當于iOS中的push效果), 上下是modal(相當于iOS中的modal效果)
- card: 普通app常用的左右切換。
- modal: 上下切換。
- headerMode: 導航欄的顯示模式: screen: 有漸變透明效果, float: 無透明效果, none: 隱藏導航欄。
- float: 無透明效果, 默認。
- screen: 有漸變透明效果, 如微信QQ的一樣。
- none: 隱藏導航欄。
- headerBackTitleVisible : 提供合理的默認值以確定后退按鈕標題是否可見,但如果要覆蓋它,則可以使用true或` false 在此選項中。
- fade-in-place: 標題組件交叉淡入淡出而不移動,類似于iOS的Twitter,Instagram和Facebook應用程序。 這是默認值。
- uikit: iOS的默認行為的近似值。 headerTransitionPreset: 指定在啟用headerMode:float時header應如何從一個屏幕轉換到另一個屏幕。
- cardStyle: 樣式(iOS上頁面切換會有白色漸變蒙層,想去掉則可以這樣設置,cardStyle: { opacity: null },切換頁面時的頁面邊框也在這里可以設置)。
- onTransitionStart: 頁面切換開始時的回調函數 (我們可以在這里注冊一些通知,告知我們切面切換的狀態,方便后面處理頁面切換事件)。
- onTransitionEnd: 頁面切換結束時的回調函數。
navigationOptions(屏幕導航選項)
支持一下參數:
- title: 可以作為headerTitle的備選字段(當沒設置headerTitle時會用該字段作為標題),也可以作為TabNavigator的tabBarLabel以及DrawerNavigator的drawerLabel。
- header: 自定義導航條,可以通過設置null來隱藏導航條;
- headerTitle: 標題;
- headerTitleAllowFontScaling: 標題是否允許縮放,默認true;
- headerBackTitle: 定義在iOS上當前頁面進入到下一頁面的回退標題,可以通過設置null來禁用它;
- headerTruncatedBackTitle: 當回退標題不能顯示的時候顯示此屬性的標題,比如回退標題太長了;
- headerBackImage:React 元素或組件在標題的后退按鈕中顯示自定義圖片。 當組件被調用時,它會在渲染時收到許多 props 如:(tintColor,title)。 默認為帶有 react-navigation/views/assets/back-icon.png 這張圖片的組件,后者是平臺的默認后圖標圖像(iOS上為向左的符號,Android上為箭頭)。
- headerRight: 定義導航欄右邊視圖;
- headerLeft: 定義導航欄左邊視圖;
- headerStyle: 定義導航欄的樣式,比如背景色等;
- headerTitleStyle: 定義標題的樣式;
- headerLeftContainerStyle:自定義 headerLeft 組件容器的樣式,例如,增加 padding。
- headerRightContainerStyle:自定義 headerRight 組件容器的樣式,,例如,增加 padding。
- headerTitleContainerStyle:自定義 headerTitle 組件容器的樣式, 例如,增加 padding。
- headerBackTitleStyle: 定義返回標題的樣式;
- headerPressColorAndroid:顏色為材料波紋 (Android >= 5.0);
- headerTintColor: 定義導航條的tintColor,會覆蓋headerTitleStyle中的顏色;
- headerTransparent:默認為 false。如果 true, 則標頭將不會有背景, 除非您顯式提供 headerStyle 或 headerBackground。
- headerBackground:與headerTransparent一起使用,以提供在標題后臺呈現的組件。 例如,您可以使用模糊視圖來創建半透明標題。
- gesturesEnabled: 定義是否能側滑返回,iOS默認true,Android默認false;
- gestureResponseDistance: 定義滑動返回的有效距離,水平狀態下默認:25,垂直狀態默認135;
- gestureDirection: 設置關閉手勢的方向。默認從左向右,可以設置從右到左的滑動操作。
創建一個StackNavigator類型的導航器
export const AppStackNavigator = createStackNavigator({
HomePage: {
screen: HomePage
},
Page1: {
screen: Page1,
navigationOptions: ({navigation}) => ({
title: `${navigation.state.params.name}頁面名`//動態設置navigationOptions
})
},
Page2: {
screen: Page2,
navigationOptions: {//在這里定義每個頁面的導航屬性,靜態配置
title: "This is Page2.",
}
},
Page3: {
screen: Page3,
navigationOptions: (props) => {//在這里定義每個頁面的導航屬性,動態配置
const {navigation} = props;
const {state, setParams} = navigation;
const {params} = state;
return {
title: params.title ? params.title : 'This is Page3',
headerRight: (
<Button
title={params.mode === 'edit' ? '保存' : '編輯'}
onPress={() =>
setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
/>
),
}
}
},
}, {
defaultNavigationOptions: {
// header: null,// 可以通過將header設為null 來禁用StackNavigator的Navigation Bar
}
});
配置navigationOptions:
步驟一的代碼中通過兩種方式配值了navigationOptions:
靜態配置:
對Page2的navigationOptions配置是通過靜態配置完成的:
Page2: {
screen: Page2,
navigationOptions: {//在這里定義每個頁面的導航屬性,靜態配置
title: "This is Page2.",
}
},
這種方式被稱為靜態配置,因為navigationOptions中的參數是直接Hard Code的不依賴于變量。
動態配置:
對Page3的navigationOptions配置是通過動態配置完成的:
Page3: {
screen: Page3,
navigationOptions: (props) => {//在這里定義每個頁面的導航屬性,動態配置
const {navigation} = props;
const {state, setParams} = navigation;
const {params} = state;
return {
title: params.title ? params.title : 'This is Page3',
headerRight: (
<Button
title={params.mode === 'edit' ? '保存' : '編輯'}
onPress={() =>
setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
/>
),
}
}
},
從上述代碼中可以看出Page3的navigationOptions依賴于props這個變量所以是動態的,當props中的內容發生變化時,navigationOptions也會跟著變化;
提示:除了在創建createStackNavigator時配置navigationOptions外,在StackNavigator之外也可以配置navigationOptions;
createStackNavigator之外也可以配置navigationOptions
方式一:
Page2.navigationOptions = {
title: "This is Page2.",
};
方式二:
export default class Page1 extends React.Component {
//也可在這里定義每個頁面的導航屬性,這里的定義會覆蓋掉別處的定義
static navigationOptions = {
title: 'Page1',
};
...
第三步:界面跳轉
export default class HomePage extends React.Component {
//在這里定義每個頁面的導航屬性
static navigationOptions = {
title: 'Home',
headerBackTitle:'返回哈哈',//設置返回此頁面的返回按鈕文案,有長度限制
}
render() {
const {navigation} = this.props;
return <View style=>
<Text style={styles.text}>歡迎來到HomePage</Text>
<Button
title="Go To Page1"
onPress={() => {
navigation.navigate('Page1', {name: '動態的'});
}}
/>
<Button
title="Go To Page2"
onPress={() => {
navigation.navigate('Page2');
}}
/>
<Button
title="Go To Page3"
onPress={() => {
navigation.navigate('Page3',{ name: 'Devio' });
}}
/>
</View>
}
}
代碼解析:
頁面跳轉可分為兩步:
-
- 獲取navigation:
const {navigation} = this.props;
-
- 通過
navigate(routeName, params, action)
進行頁面跳轉:
navigation.navigate('Page2'); navigation.navigate('Page3',{ name: 'Devio' });
這里在跳轉到
Page3
的時候傳遞了參數{ name: 'Devio' }
; - 通過
第四步:更新頁面Params與返回
export default class Page3 extends React.Component {
render() {
const {navigation} = this.props;
const {state, setParams} = navigation;
const {params} = state;
const showText = params.mode === 'edit' ? '正在編輯' : '編輯完成';
return <View style=>
<Text style={styles.text}>歡迎來到Page3</Text>
<Text style={styles.showText}>{showText}</Text>
<TextInput
style={styles.input}
onChangeText={text=>{
setParams({title:text})
}}
/>
<Button
title="Go Back"
onPress={() => {
navigation.goBack();
}}
/>
</View>
}
}
代碼解析:
在上述代碼中通過:
<TextInput
style={styles.input}
onChangeText={text=>{
setParams({title:text})
}}
/>
將輸入框中內容的變化,通過setParams({title:text})
更新到頁面的標題上,你會看到當輸入框中內容發生變化時,標題也會跟著變。
當用戶單擊Go Back
按鈕時,通過:
navigation.goBack();
實現了返回上一頁;
createBottomTabNavigator-底部導航
相當于iOS里面的TabBarController
createBottomTabNavigator API
createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig):
-
RouteConfigs
(必選):路由配置對象是從路由名稱到路由配置的映射,告訴導航器該路由呈現什么。 -
BottomTabNavigatorConfig
(可選):配置導航器的路由(如:默認首屏,navigationOptions,paths等)樣式(如,轉場模式mode、頭部模式等)。
從createBottomTabNavigator API上可以看出createBottomTabNavigator
支持通過RouteConfigs
和 BottomTabNavigatorConfig
兩個參數來創建createBottomTabNavigator導航器。
RouteConfigs
RouteConfigs支持三個參數screen
、path
以及navigationOptions
;
-
screen
(必選):指定一個 React 組件作為屏幕的主要顯示內容,當這個組件被TabNavigator加載時,它會被分配一個navigation
prop。 -
path
(可選):用來設置支持schema跳轉時使用,具體使用會在下文的有關Schema
章節中講到; -
navigationOptions
(可選):用以配置全局的屏幕導航選項如:title、headerRight、headerLeft等;
BottomTabNavigatorConfig
- tabBarComponent:指定createBottomTabNavigator的TabBar組件,如果不指定在iOS上默認使用TabBarBottom,在Android平臺上默認使用TabBarTop。
-
TabBarBottom
與TabBarTop
都是react-navigation
所支持的組件,要自定義TabBar可以重寫這兩個組件也可以根據需要自己實現一個;
-
- tabBarOptions: 配置TaBar下文會詳細講解;
- initialRouteName : 默認頁面組件,createBottomTabNavigator顯示的第一個頁面;
- order: 定義tab順序的routeNames數組。
- paths: 提供routeName到path config的映射,它覆蓋routeConfigs中設置的路徑。
- backBehavior: 后退按鈕是否會導致標簽切換到初始tab? 如果是,則設切換到初始tab,否則什么也不做。 默認為切換到初始tab。
tabBarOptions(tab配置)
- activeTintColor: 設置TabBar選中狀態下的標簽和圖標的顏色;
- inactiveTintColor: 設置TabBar非選中狀態下的標簽和圖標的顏色;
- showIcon: 是否展示圖標,默認是false;
- showLabel: 是否展示標簽,默認是true;
- upperCaseLabel - 是否使標簽大寫,默認為true。
- tabStyle: 設置單個tab的樣式;
- indicatorStyle: 設置 indicator(tab下面的那條線)的樣式;
- labelStyle: 設置TabBar標簽的樣式;
- iconStyle: 設置圖標的樣式;
- style: 設置整個TabBar的樣式;
- allowFontScaling: 設置TabBar標簽是否支持縮放,默認支持;
- safeAreaInset:覆蓋的forceInset prop,默認是{ bottom: 'always', top: 'never' },可選值:top | bottom | left | right ('always' | 'never');
navigationOptions(屏幕導航選項)
createBottomTabNavigator支持的屏幕導航選項的參數有:
- title: 可以用作headerTitle和tabBarLabel的備選的通用標題。
- tabBarVisible: 顯示或隱藏TabBar,默認顯示;
- tabBarIcon: 設置TabBar的圖標;
- tabBarLabel: 設置TabBar的標簽;
- tabBarOnPress: Tab被點擊的回調函數,它的參數是一保函一下變量的對象:
- navigation: navigation prop ;
- defaultHandler: tab按下的默認處理程序;
- tabBarButtonComponent:React組件,它包裝圖標和標簽并實現onPress。 默認情況下是TouchableWithoutFeedback的一個封裝,使其其表現與其它可點擊組件相同,tabBarButtonComponent: TouchableOpacity 將使用 TouchableOpacity 來替代;
- tabBarAccessibilityLabel:選項卡按鈕的輔助功能標簽。 當用戶點擊標簽時,屏幕閱讀器會讀取這些信息。 如果您沒有選項卡的標簽,建議設置此項;
- tabBarTestID:用于在測試中找到該選項卡按鈕的 ID;
案例
export const AppTabNavigator = createBottomTabNavigator({
Page1: {
screen: Page1,
navigationOptions: {
tabBarLabel: 'Page1',
tabBarIcon: ({tintColor, focused}) => (
<Ionicons
name={focused ? 'ios-home' : 'ios-home-outline'}
size={26}
style=
/>
),
}
},
Page2: {
screen: Page2,
navigationOptions: {
tabBarLabel: 'Page2',
tabBarIcon: ({tintColor, focused}) => (
<Ionicons
name={focused ? 'ios-people' : 'ios-people-outline'}
size={26}
style=
/>
),
}
},
Page3: {
screen: Page3,
navigationOptions: {
tabBarLabel: 'Page3',
tabBarIcon: ({tintColor, focused}) => (
<Ionicons
name={focused ? 'ios-chatboxes' : 'ios-chatboxes-outline'}
size={26}
style=
/>
),
}
},
}, {
tabBarComponent: TabBarComponent,
tabBarOptions: {
activeTintColor: Platform.OS === 'ios' ? '#e91e63' : '#fff',
}
});
在上述代碼中使用了react-native-vector-icons
的矢量圖標作為Tab的顯示圖標,tabBarIcon接收一個React 組件,大家可以根據需要進行定制:
- tintColor: 當前狀態下Tab的顏色;
- focused: Tab是否被選中;
react-native-vector-icons
安裝
yarn add react-native-vector-icons
react-native link react-native-vector-icons
圖標庫地址:
https://oblador.github.io/react-native-vector-icons/
createMaterialTopTabNavigator-頂部導航
createMaterialTopTabNavigator API
createMaterialTopTabNavigator(RouteConfigs, TabNavigatorConfig):
-
RouteConfigs
(必選):路由配置對象是從路由名稱到路由配置的映射,告訴導航器該路由呈現什么。 -
TabNavigatorConfig
(可選):配置導航器的路由(如:默認首屏,navigationOptions,paths等)樣式(如,轉場模式mode、頭部模式等)。
從createMaterialTopTabNavigator API上可以看出createMaterialTopTabNavigator
支持通過RouteConfigs
和 TabNavigatorConfig
兩個參數來創建createMaterialTopTabNavigator導航器。
RouteConfigs
RouteConfigs支持三個參數screen
、path
以及navigationOptions
;
-
screen
(必選):指定一個 React 組件作為屏幕的主要顯示內容,當這個組件被TabNavigator加載時,它會被分配一個navigation
prop。 -
path
(可選):用來設置支持schema跳轉時使用,具體使用會在下文的有關Schema
章節中講到; -
navigationOptions
(可選):用以配置全局的屏幕導航選項如:title、headerRight、headerLeft等;
TabNavigatorConfig
- tabBarComponent:指定TabNavigator的TabBar組件;
- tabBarPosition: 用于指定TabBar的顯示位置,支持’top’ 與 ‘bottom’兩種方式;
- swipeEnabled : 是否可以左右滑動切換tab;
- lazy - 默認值是 false。如果是true,Tab 頁只會在被選中或滑動到該頁時被渲染。當為 false 時,所有的 Tab 頁都將直接被渲染;(可以輕松實現多Tab 頁面的懶加載);
- optimizationsEnabled -是否將 Tab 頁嵌套在到 中。如果是,一旦該 Tab 頁失去焦點,將被移出當前頁面, 從而提高內存使用率。
- animationEnabled : 切換頁面時是否有動畫效果。
- initialLayout : 包含初始高度和寬度的可選對象可以被傳遞以防止react-native-tab-view呈現中的一個幀延遲;
- tabBarOptions: 配置TaBar下文會詳細講解;
- initialRouteName : 默認頁面組件,TabNavigator顯示的第一個頁面;
- order: 定義tab順序的routeNames數組。
- paths: 提供routeName到path config的映射,它覆蓋routeConfigs中設置的路徑。
- backBehavior: 后退按鈕是否會導致標簽切換到初始tab? 如果是,則設切換到初始tab,否則什么也不做。 默認為切換到初始tab。
tabBarOptions(tab配置)
- activeTintColor: 設置TabBar選中狀態下的標簽和圖標的顏色;
- inactiveTintColor: 設置TabBar非選中狀態下的標簽和圖標的顏色;
- showIcon: 是否展示圖標,默認是false;
- showLabel: 是否展示標簽,默認是true;
- upperCaseLabel - 是否使標簽大寫,默認為true。
- tabStyle: 設置單個tab的樣式;
- indicatorStyle: 設置 indicator(tab下面的那條線)的樣式;
- labelStyle: 設置TabBar標簽的樣式;
- iconStyle: 設置圖標的樣式;
- style: 設置整個TabBar的樣式;
- allowFontScaling: 設置TabBar標簽是否支持縮放,默認支持;
- pressColor -Color for material ripple(僅支持 Android >= 5.0;
- pressOpacity -按下標簽時的不透明度(支持 iOS 和 Android < 5.0);
- scrollEnabled -是否支持 選項卡滾動
navigationOptions(屏幕導航選項)
createMaterialTopTabNavigator支持的屏幕導航選項的參數有:
- title: 可以用作headerTitle和tabBarLabel的備選的通用標題。
- swipeEnabled:是否允許tab之間的滑動切換,默認允許;
- tabBarIcon: 設置TabBar的圖標;
- tabBarLabel: 設置TabBar的標簽;
- tabBarOnPress: Tab被點擊的回調函數,它的參數是一保函一下變量的對象:
- navigation:頁面的 navigation props
- defaultHandler: tab press 的默認 handler
- tabBarAccessibilityLabel:選項卡按鈕的輔助功能標簽。 當用戶點擊標簽時,屏幕閱讀器會讀取這些信息。 如果您沒有選項卡的標簽,建議設置此項;
- tabBarTestID:用于在測試中找到該選項卡按鈕的 ID;
createDrawerNavigator-抽屜導航
createDrawerNavigator API
createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig):
-
RouteConfigs
(必選):路由配置對象是從路由名稱到路由配置的映射,告訴導航器該路由呈現什么。 -
DrawerNavigatorConfig
(可選):配置導航器的路由(如:默認首屏,navigationOptions,paths等)樣式(如,轉場模式mode、頭部模式等)。
從createDrawerNavigator API上可以看出createDrawerNavigator
支持通過RouteConfigs
和 DrawerNavigatorConfig
兩個參數來創建createDrawerNavigator導航器。
RouteConfigs
RouteConfigs支持三個參數screen
、path
以及navigationOptions
;
-
screen
(必選):指定一個 React 組件作為屏幕的主要顯示內容,當這個組件被DrawerNavigator加載時,它會被分配一個navigation
prop。 -
path
(可選):用來設置支持schema跳轉時使用,具體使用會在下文的有關Schema
章節中講到; -
navigationOptions
(可選):用以配置全局的屏幕導航選項如:title、headerRight、headerLeft等;
DrawerNavigatorConfig
- drawerWidth: 設置側邊菜單的寬度;
- drawerPosition: 設置側邊菜單的位置,支持’left’、 ‘right’,默認是’left’;
- contentComponent: 用于呈現抽屜導航器內容的組件,例如導航項。接收抽屜導航器的 navigation 屬性 。默認為DrawerItems。有關詳細信息,請參閱下文;
- contentOptions: 配置抽屜導航器內容,見下文;
- useNativeAnimations: 是否啟用Native動畫,默認啟用;
- drawerBackgroundColor: 側邊菜單的背景;
- initialRouteName: 初始化哪個界面為根界面,如果不配置,默認使用RouteConfigs中的第一個頁面當做根界面;
- order: drawer排序,默認使用配置路由的順序;
- paths: 提供routeName到path config的映射,它覆蓋routeConfigs中設置的路徑。
- backBehavior: 后退按鈕是否會導致標簽切換到初始drawer? 如果是,則設切換到初始drawer,否則什么也不做。 默認為切換到初始drawer。
import React,{Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button
} from 'react-native';
import { createDrawerNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
const HomeScreen=({navigation})=>(
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>HomeScreen</Text>
<Button
onPress={()=>(navigation.toggleDrawer())}
title="Open Drawer"
></Button>
</View>
);
const ProfileScreen=()=>(
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}><Text>ProfileScreen</Text></View>
);
const RootDrawer =createDrawerNavigator({
Home:{
screen:HomeScreen,
navigationOptions:{
drawerLabel:'MyHome',
drawerIcon:({tintColor, focused })=>(
<Ionicons
name={'ios-home'}
size={20}
style={{ color: tintColor }}
></Ionicons>
),
},
},
Profile:{
screen:ProfileScreen,
navigationOptions:{
drawerLabel:'MyProfile',
drawerIcon:({tintColor})=>(
<Ionicons
name={'ios-person'}
size={20}
style={{color:tintColor}}
></Ionicons>
),
},
}
});
export default RootDrawer;
自定義側邊欄(contentComponent)
DrawerNavigator有個默認的帶滾動的側邊欄,你也可以通過重寫這個側邊欄組件來自定義側邊欄:
contentComponent:(props) => (
<ScrollView style=>
<SafeAreaView forceInset=>
<DrawerItems {...props} />
</SafeAreaView>
</ScrollView>
)
DrawerItems的contentOptions
contentOptions主要配置側滑欄item的屬性,只對DrawerItems,例如我們剛才寫的例子,就可以通過這個屬性來配置顏色,背景色等。其主要屬性有:
- items: 路由數組,如果要修改路由可以可以修改或覆蓋它;
- activeItemKey: 定義當前選中的頁面的key;
- activeTintColor: 選中item狀態的文字顏色;
- activeBackgroundColor: 選中item的背景色;
- inactiveTintColor: 未選中item狀態的文字顏色;
- inactiveBackgroundColor: 未選中item的背景色;
- onItemPress: 選中item的回調,這個參數屬性為函數,會將當前路由回調過去;
- itemsContainerStyle: 定義itemitem容器的樣式;
- itemStyle: 定義item的樣式;
- labelStyle: 定義item文字的樣式;
- iconContainerStyle: 定義item圖標容器的樣式;
- activeLabelStyle:選中狀態下文本樣式;
- inactiveLabelStyle:非選中狀態下文本樣式;
- iconContainerStyle :用于設置圖標容器的樣式。
eg:
contentOptions: {
activeTintColor: '#e91e63',
itemsContainerStyle: {
marginVertical: 0,
},
iconContainerStyle: {
opacity: 1
}
}
navigationOptions(屏幕導航選項)
DrawerNavigator支持的屏幕導航選項的參數有:
title: 可以用作headerTitle和drawerLabel的備選的通用標題。
drawerLabel:側滑標題;
-
drawerIcon:側滑的標題圖標,這里會回傳兩個參數:
-
{focused: boolean, tintColor: string}
- focused: 表示是否是選中狀態;
- tintColor: 表示選中的顏色;
-
drawerLockMode:指定抽屜的鎖定模式。 這也可以通過在頂級路由器上使用screenProps.drawerLockMode 動態更新。
側邊欄操作(打開、關閉、切換)
側邊欄支持以下幾種操作方式:
navigation.openDrawer();
navigation.closeDrawer();
navigation.toggleDrawer();
//或
navigation.dispatch(DrawerActions.openDrawer());
navigation.dispatch(DrawerActions.closeDrawer());
navigation.dispatch(DrawerActions.toggleDrawer());
其中路由名openDrawer
對應這打開側邊欄的操作,DrawerClose
對應關閉側邊欄的操作,toggleDrawer
對應切換側邊欄操作,要進行這些操作我么還需要一個navigation
,navigation
可以從props中獲取;
- 打開側邊欄:
navigation.openDrawer();
; - 關閉側邊欄:
navigation.closeDrawer();
; - 切換側邊欄:
navigation.toggleDrawer();
;
createSwitchNavigator-開關導航
SwitchNavigator 的用途是一次只顯示一個頁面。 默認情況下,它不處理返回操作,并在你切換時將路由重置為默認狀態。
createSwitchNavigator API
createSwitchNavigator(RouteConfigs, SwitchNavigatorConfig):
-
RouteConfigs
(必選,同createStackNavigator的RouteConfigs):路由配置對象是從路由名稱到路由配置的映射,告訴導航器該路由呈現什么。 -
SwitchNavigatorConfig
(可選):配置導航器的路由;
SwitchNavigatorConfig
幾個被傳遞到底層路由以修改導航邏輯的選項:
- initialRouteName -第一次加載時初始選項卡路由的 routeName。
- resetOnBlur - 切換離開屏幕時,重置所有嵌套導航器的狀態。 默認為true。
- paths - 提供 routeName 到 path 配置的映射, 它重寫 routeConfigs 中設置的路徑。
- backBehavior - 控制 “返回” 按鈕是否會導致 Tab 頁切換到初始 Tab 頁? 如果是, 設置為 initialRoute, 否則 none。 默認為none行為。
const AppStack = createStackNavigator({
Home: {
screen: HomePage
},
Page1: {
screen: Page1
}
});
const AuthStack = createStackNavigator({
Login: {
screen: Login
},
},{
navigationOptions: {
// header: null,// 可以通過將header設為null 來禁用StackNavigator的Navigation Bar
}
});
export default createSwitchNavigator(
{
Auth: AuthStack,
App: AppStack,
},
{
initialRouteName: 'Auth',
}
);
你的贊是我前進的動力
求贊,求評論,求分享...