React Native導航器Navigator前端
使用導航器可讓你在應用的不一樣場景(頁面)間進行切換。導航器經過路由對象來分辨不一樣的場景。利用renderScene方法,導航欄能夠根據指定的路由來渲染場景。能夠經過configureScene屬性獲取指定路由對象的配置信息,從而改變場景的動畫或者手勢。——以上內容摘錄自React Native中文網react
可選的函數,用來配置場景動畫和手勢。會帶有兩個參數調用,一個是當前的路由,一個是當前的路由棧。而後它應當返回一個場景配置對象。android
使用方式:react-native
(route, routeStack) => Navigator.SceneConfigs.FloatFromRightapp
切換效果有:ide
Navigator.SceneConfigs.PushFromRight (默認)函數
Navigator.SceneConfigs.FloatFromRight動畫
Navigator.SceneConfigs.FloatFromLeftthis
Navigator.SceneConfigs.FloatFromBottomspa
Navigator.SceneConfigs.FloatFromBottomAndroid
Navigator.SceneConfigs.FadeAndroid
Navigator.SceneConfigs.HorizontalSwipeJump
Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
Navigator.SceneConfigs.VerticalUpSwipeJump
Navigator.SceneConfigs.VerticalDownSwipeJump
類類型的屬性,定義啓動時加載的路由。路由是導航欄用來識別渲染場景的一個對象。initialRoute必須是initialRouteStack中的一個路由。initialRoute默認爲initialRouteStack中最後一項。
類類型的屬性,用來在Navigator組件初加載時提供導航路徑。若是沒有向Navigator組件提供initialRoute屬性,就必須提供initialRouteStack屬性;若是提供了initialRoute但沒有提供initialRouteStack,那麼React Native會生成一個只有initialRoute元素的數據做爲initialRouteStack。
該屬性返回一個能夠渲染的節點,這個節點能夠用做全部界面的通用導航欄。當開發者決定使用navigationBar來進行導航時,大部分應用界面的導航欄都具備相同的格式(相同大小的按鈕、標題欄等),只是按鈕的圖片或者標題欄中的文字各有不一樣。
給Navigator組件指定導航欄的示例以下:
navigationBar = {
<Navigator.NavigationBar routeMapper={ navigationBarRouteMapper}/>
}
Navigator.NavigationBar是一個可顯示的React Native組件,它必須有一個routeMapper屬性。開發者必須將一個對象指定給routeMapper屬性。這個對象能夠有三個成員變量:LeftButton、RightButton、Title。其中,Title成員變量必須有。這三個成員變量要求都是函數類型的,Navigator組件渲染導航欄時,使用這三個函數的返回值渲染導航欄的對應區域。
每一個函數能夠接收4個參數。示例:
LeftButton: function( route, navigator, index, navState)
在三個成員函數返回的可渲染節點的樣式中設置三個區域的大小。這三個函數返回的可渲染節點就是三個區域中顯示的內容。
不一樣的頁面須要控制這三個區域中顯示不一樣的內容,開發者須要將不一樣頁面待顯示的不一樣內容(文字、圖片)經過route傳入這三個函數中,而後這三個函數從route的成員變量中去處傳入的供顯示的不一樣內容,最後渲染顯示。
對按鈕或輸入框的處理,一般都須要調用父組件的函數,這就須要將這個父組件的函數以某種方式傳入routeMapper屬性中。開發者沒法直接給routeMapper屬性再傳值,可是能夠放在route中,由Natigator組件在渲染時交給routeMapper屬性。而route中的成員變量,都是由開發者提供的,而且對每一個事件只能提供一個回調函數,準確地說,是最近一次提供的回調函數會覆蓋上一次提供的回調函數。
提供從父導航器得到的導航器對象。
每當導航切換完成或初始化以後,調用此回調,參數爲新場景的路由。
React native鼓勵開發者使用navigationContext.addListener(‘didfocus’,callback)事件監聽器來實現相同的功能。
會在導航切換以前調用,參數爲目標路由。
React native鼓勵開發者使用navigationContext.addListener(‘willfocus’,callback)事件監聽器來實現相同的功能。
必要參數。用來渲染指定路由的場景。調用的參數是路由和導航器。
指定的樣式將被應用到每個切換的場景中。
獲取當前棧裏的路由,也就是push進來,沒有pop掉的那些。
退回到上一個界面而不卸載當前界面。
沿界面路徑向前跳一個界面而不卸載當前界面。
跳轉到某個界面而不卸載任何界面。
導航組件在路徑列表最前端添加一個新的界面,並立刻跳轉至這個界面。
導航器退回一個界面並卸載原界面。
用一個新的路由替換掉當前場景。
使用一個新的界面替代路徑表中的第index個界面,但不改變當前顯示界面。
replacePrevious(route)
將當前導航路徑的上一個界面使用指定的界面替代。
跳轉到新的場景,而且重置整個路由棧。
使用給定的路徑表替換當前的路徑列表。
popToRoute(route)
導航器回退到指定的界面,而且將這個過程當中回退過的界面都卸載。
導航器回退到的第一個場景,卸載掉全部的其餘場景。
實現的效果爲:第一個界面向第二個界面傳值,在第二個界面中改變第一個界面的顯示內容。
index.android.js
1 import React from 'react'; 2 import { 3 View, 4 Navigator, 5 AppRegistry 6 } from 'react-native'; 7 import FirstPageComponent from './js/FirstPageComponent'; 8 export default class SampleComponent extends React.Component { 9 render() { 10 let defaultName = 'FirstPageComponent'; 11 let defaultComponent = FirstPageComponent; 12 return ( 13 <Navigator 14 initialRoute={{ name: defaultName, component: defaultComponent }} 15 configureScene={(route) => { 16 return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight; 17 }} 18 renderScene={(route, navigator) => { 19 let Component = route.component; 20 return <Component {...route.params} navigator={navigator} /> 21 }} 22 /> 23 ); 24 } 25 } 26 27 AppRegistry.registerComponent('listen1', () => SampleComponent);
第一個界面
1 import React from 'react'; 2 import { 3 View, 4 Navigator, 5 TouchableOpacity, 6 Text, 7 } from 'react-native'; 8 9 import SecondPageComponent from './SecondPageComponent'; 10 11 export default class FirstPageComponent extends React.Component { 12 13 constructor(props) { 14 super(props); 15 16 this.state = { 17 id: 2, 18 user: null, 19 } 20 } 21 22 23 _pressButton() { 24 let _this = this; 25 const { navigator } = this.props; 26 if(navigator) { 27 navigator.push({ 28 name: 'SecondPageComponent', 29 component: SecondPageComponent, 30 params: { 31 id: this.state.id, 32 //從SecondPageComponent獲取user 33 getUser: function(user) { 34 _this.setState({ 35 user: user 36 }) 37 } 38 } 39 }); 40 } 41 } 42 43 render() { 44 if( this.state.user ) { 45 return( 46 <View> 47 <Text>用戶信息: { JSON.stringify(this.state.user) }</Text> 48 </View> 49 ); 50 }else { 51 return( 52 <View> 53 <TouchableOpacity onPress={this._pressButton.bind(this)}> 54 <Text>查詢ID爲{ this.state.id }的用戶信息</Text> 55 </TouchableOpacity> 56 </View> 57 ); 58 } 59 60 } 61 }
第二個界面
1 const USER_MODELS = { 2 1: { name: 'mot', age: 23 }, 3 2: { name: '晴明大大', age: 25 } 4 }; 5 6 import React from 'react'; 7 import { 8 View, 9 Navigator, 10 TouchableOpacity, 11 Text, 12 } from 'react-native'; 13 14 import FirstPageComponent from './FirstPageComponent'; 15 16 export default class SecondPageComponent extends React.Component { 17 18 constructor(props) { 19 super(props); 20 this.state = { 21 id: null 22 } 23 } 24 25 componentDidMount() { 26 //這裏獲取從FirstPageComponent傳遞過來的參數: id 27 this.setState({ 28 id: this.props.id 29 }); 30 } 31 32 _pressButton() { 33 const { navigator } = this.props; 34 35 if(this.props.getUser) { 36 let user = USER_MODELS[this.props.id]; 37 this.props.getUser(user); 38 } 39 40 if(navigator) { 41 navigator.pop(); 42 } 43 } 44 45 render() { 46 return( 47 <View> 48 <Text>得到的參數: id={ this.state.id }</Text> 49 <TouchableOpacity onPress={this._pressButton.bind(this)}> 50 <Text>點我跳回去</Text> 51 </TouchableOpacity> 52 </View> 53 ); 54 } 55 }
在第二個界面中修改第一個界面的原理是:在第一個界面中聲明一個方法,能夠更改其state。咱們知道,state發生改變,界面就會從新渲染。在傳值的時候,將該方法做爲一個屬性傳給第二個界面。在第二個界面中執行該方法,就從新渲染了第一個界面。只不過此時的第一界面沒有在屏幕上。當第二個界面卸載(pop)後,返回第一個界面,就看到了更改後的第一個界面。