[深入剖析React Native]React Native元件之Navigator
1.簡介
導航元件Navigator可以讓app在不同頁面進行切換。為達到這樣的功能,Navigator提供了路由物件功能進行區分每個頁面。
我們可以通過renderScene方法,Navaigator根據指定的路由進行渲染指定的介面。
除了以上功能之外,為了改變頁面切換的動畫或者頁面的手勢,該元件還提供configureScene屬性來進行獲取指定路由頁面的配置物件資訊。
對於頁面切換動畫或者更多的螢幕配置選項資訊詳情可以檢視Navigator.SceneConfigs
2.動畫手勢屬性
PushFromRight
FloatFromRight
FloatFromLeft
FloatFromBottom
FloatFromBottomAndroid
FadeAndroid
HorizontalSwipeJump
HorizontalSwipeJumpFromRight
VertivalUpSwipeJump
VertivalDownSwipeJump
更多屬性,可以去修改NavigatorSceneConfigs.js這個檔案。
3.Navigator方法
在使用導航器的時候,如果你已經獲取了導航器物件的引用,我們可以進行呼叫以下一些方法來實現頁面導航功能:getCurrentRoutes() 該進行返回存在的路由列表資訊
getCurrentRoutes() 返回存在的路由列表資訊
jumpBack() 回退操作,但是不會解除安裝(刪除)當前頁面
jumpForward() 跳轉到相對於當前頁面的下一個頁面
jumpTo(route) 根據傳入的路由資訊,跳轉到一個指定的頁面(該頁面不會解除安裝刪除)
push(route) 導航切換到一個新的頁面,新的頁面進行壓入棧。通過jumpForward()方法可以回退過去
pop 當前頁面彈出來,跳轉到棧中下一個頁面,並且解除安裝刪除掉當前的頁面
replace(route) 只用傳入的路由的指定頁面進行替換掉當前的頁面
replaceAtIndex(route, index) 傳入路由以及位置索引,使用該路由指定的頁面跳轉到指定位置的頁面
replacePrevious(route) 傳入路由,通過指定路由的頁面替換掉前一個頁面
resetTo(route) 進行導航到新的介面,並且重置整個路由棧
immediatelyResetRouteStack(routeStack) 該通過一個路由頁面陣列來進行重置路由棧
popToRoute(route) 進行彈出相關頁面,跳轉到指定路由的頁面,彈出來的頁面會被解除安裝刪除
popToTop() 進行彈出頁面,導航到棧中的第一個頁面,彈出來的所有頁面會被解除安裝刪除
4.Navigator屬性風格
configureScene -- function 方法, 該為可選的方法進行配置頁面切換動畫和手勢。該會通過路由和路由棧兩個引數呼叫,進行返回一個頁面引數配置物件:(route, routeStack) => Navigator.SceneConfigs.FloatFromRight
initialRoute -- object 引數物件, 進行設定導航初始化的路由頁面。路由是標識導航器渲染標識每一個頁面的物件。initialRoute必須為initialRouteStack中的路由。同時initialRoute預設為initialRouteStack中路由棧的最後一項
initialRouteStack -- [object] 引數物件陣列 該是一個初始化的路由陣列進行初始化。如果initalRoute屬性沒有設定的話,那麼就必須設定initialRouteStack屬性,使用該最後一項作為初始路由。 如果initalRouteStack屬性沒有設定的話,該會生成只包含initalRoute值的陣列
navigationBar -- node 該為可選的引數,在頁面切換中用來提供一個導航欄
navigator -- object 該為可選引數,可以從父類導航器中獲取導航器物件
onDidFoucs -- function 該方法已經廢棄,我們可以使用navigationContext.addListener(‘didfocus’,callback)方法進行替代。該會在每次頁面切換完成或者初始化之後進行呼叫該方法。該引數為新頁面的路由
onWillFocus --function 該方法已經廢棄,我們可以使用navigationContext.addListener(‘willfocus’,callback)方法進行替代。該會頁面每次進行切換之前呼叫
renderScene -- function 該為必須呼叫的方法,該用來渲染每一個路由指定的頁面。引數為路由以及導航器物件兩個引數,具體是方法如下:
(route, navigator) =><MySceneComponent title={route.title} navigator={navigator} />
sceneStyle -- 樣式風格,該繼承了View檢視的所有樣式風格。該設定用於每個頁面容器的風格
5.例項
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableHighlight,
} from 'react-native';
class NavButton extends Component {
render() {
return (
<TouchableHighlight
style={styles.button}
underlayColor="#B5B5B5"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>{this.props.text}</Text>
</TouchableHighlight>
);
}
}
class HomeScene extends Component {
render() {
return(
<View style={styles.container}>
<NavButton
onPress={() => {
this.props.navigator.push({
component: ConfigsScene,
name: '手勢屬性',
});
}}
text='手勢屬性'
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: MethodsScene,
name: '方法',
});
}}
text='方法'
/>
</View>
);
}
}
class ConfigsScene extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.messageText}>{this.props.message}</Text>
<NavButton
onPress={() => {
this.props.navigator.pop();
}}
text="返回上一頁"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.PushFromRight,
});
}}
text="PushFromRight default"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.FloatFromRight,
});
}}
text="FloatFromRight"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.FloatFromLeft,
});
}}
text="FloatFromLeft"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
});
}}
text="FloatFromBottom"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.FloatFromBottomAndroid,
});
}}
text="FloatFromBottomAndroid"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.FadeAndroid,
});
}}
text="FadeAndroid"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJump,
});
}}
text="HorizontalSwipeJump"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJumpFromRight,
});
}}
text="HorizontalSwipeJumpFromRight"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.VerticalUpSwipeJump,
});
}}
text="VerticalUpSwipeJump"
/>
<NavButton
onPress={() => {
this.props.navigator.push({
component: EndScene,
sceneConfig: Navigator.SceneConfigs.VerticalDownSwipeJump,
});
}}
text="VerticalDownSwipeJump"
/>
</View>
);
}
}
class MethodsScene extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.messageText}>Current Routes length: {this.props.navigator.getCurrentRoutes().length}</Text>
<NavButton
onPress={() => {
this.props.navigator.jumpBack();
}}
text='jumpBack'
/>
<NavButton
onPress={() => {
}}
text='jumpForward'
/>
<NavButton
onPress={() => {
}}
text='jumpTo'
/>
</View>
);
}
}
class EndScene extends Component {
render() {
return (
<View style={styles.container}>
<NavButton
onPress={() => {
this.props.navigator.pop();
}}
text="返回上一頁"
/>
<NavButton
onPress={() => {
this.props.navigator.popToTop();
}}
text="退到棧中第一個頁面"
/>
</View>
);
}
}
export default class NavigatorMazouri extends Component {
render() {
return (
<Navigator
style={styles.container}
initialRoute={{
component: HomeScene,
name: 'home'
}}
renderScene={(route, navigator) => {
let Component = route.component;
if(route.component) {
return <Component {...route.params} navigator={navigator} />
}
}}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.PushFromRight;
}}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#F5FCFF',
},
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
button: {
backgroundColor: 'white',
padding: 15,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#CDCDCD',
},
});