createStackNavigator
createStackNavigator
提供APP螢幕之間切換的能力,它是以棧的形式還管理螢幕之間的切換,新切換到的螢幕會放在棧的頂部。
螢幕轉場風格
預設情況下,createStackNavigator提供了轉場過渡效果,在Android和iOS上過渡效果是不同的,這也是React Native重平臺性的一個體現,在Android上從螢幕底部淡入,在iOS上是從螢幕的右側劃入,當然你也可以通過配置讓StackNavigator支援螢幕從底部滑入的效果。
createStackNavigator API
createStackNavigator(RouteConfigs, StackNavigatorConfig):
RouteConfigs
(必選):路由配置物件是從路由名稱到路由配置的對映,告訴導航器該路由呈現什麼。StackNavigatorConfig
(可選):配置導航器的路由(如:預設首屏,navigationOptions,paths等)樣式(如,轉場模式mode、頭部模式等)。
從createStackNavigator API上可以看出createStackNavigator
支援通過RouteConfigs
和 StackNavigatorConfig
兩個引數來建立createStackNavigator導航器。
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,
navigationOptions,
disableKeyboardHandling,
getCustomActionCreators
} = stackConfig;
...
複製程式碼
這7個引數可以根據作用不同分為路由配置、檢視樣式配置兩類,首先看用於路由配置的引數:
用於路由配置的引數:
- initialRouteName: 設定預設的頁面元件,必須是上面已註冊的頁面元件。
- initialRouteParams: 初始路由的引數。
- navigationOptions: 螢幕導航的預設選項,下文會詳細講解。
- 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做介面導航、配置navigationOptions
第一步:建立一個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={{flex: 1, backgroundColor: "orange",}}>
<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={{flex: 1, backgroundColor: "gray",}}>
<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();
複製程式碼
實現了返回上一頁;
類似上述的應用場景有很多,大家可以通過與本教程配套的最新版React Native+Redux打造高質量上線App視訊教程進行進一步學習react-navigation的更多高階應用。
- 大家在學習使用React Navigation3x過程中遇到任何問題都可以在React Navigation3x的視訊教程中尋找答案哈。
- 另外,也可以通過最新版React Native+Redux打造高質量上線App視訊教程學習React Navigation3x開發的更多實戰經驗和技巧,以及優化思路。