作應用確定不可能就一個界面,因此這裏涉及到咱們界面跳轉的問題,那RN是怎麼利用導航器來實現跳轉的呢?咱們結合官網給出的例子進行分析,後面筆者發現其實RN的某些思路其實跟Android大同小異,若是你對Android的啓動模式有了解還有Android的棧的理解,我相信理解這個應該不會很複雜 D)java
首先若是想用react-navigation就要先安裝它,react-navigation在React Native項目中安裝。因此咱們須要cmd指令進入項目文件夾以後進行以下命令:react
npm install --save react-navigation 下載react-navigationios
接下來,安裝react-native-gesture-handlergit
npm install --save react-native-gesture-handler github
連接全部本機依賴項npm
react-native link react-native-gesture-handlerjson
ios的同窗就不須要這麼作了……react-native
要完成針對Android的react-native-gesture-handler的安裝,請務必對如下內容進行必要的修改MainActivity.java
:app
import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.ReactRootView; import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; public class MainActivity extends ReactActivity { /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ @Override protected String getMainComponentName() { return "NavigationDemo"; } @Override protected ReactActivityDelegate createReactActivityDelegate() { return new ReactActivityDelegate(this, getMainComponentName()) { @Override protected ReactRootView createRootView() { return new RNGestureHandlerEnabledRootView(MainActivity.this); } }; } }
到此就能夠安心的使用react-navigation了,本人以前沒有這樣的步驟去作,因此出現了幾回問題,切記必定要按照這樣的步驟去安裝!ide
import React from 'react'; import { Button, View, Text } from 'react-native'; import { createStackNavigator, createAppContainer } from 'react-navigation'; // Version can be specified in package.json class HomeScreen extends React.Component { render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => this.props.navigation.navigate('Details')} /> </View> ); } } class DetailsScreen extends React.Component { render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Details Screen</Text> <Button title="Go to Details" //這裏的push至關於跳轉的時候無論當前棧裏有沒有該實例都會從新建立一個新的 onPress={() => this.props.navigation.push('Details')} /> </View> ); } } const RootStack = createStackNavigator( { Home: HomeScreen, Details: DetailsScreen, }, { initialRouteName: 'Home', } ); const AppContainer = createAppContainer(RootStack); export default class App extends React.Component { render() { return <AppContainer />; } }
這裏先貼出來代碼範例
其實有點基礎的不難看出來,程序的入口是在App而且返回渲染了AppContainer的對象,而且這個對象經過createAppContainer返回StackNavigation,對於createAppContainer這個方法網上沒有太多的資料,打開源碼解釋以下:
Create an app container to wrap the root navigator
建立一個應用程序容器來包裝根導航器
字面上的理解比較容易就是建立一個容器來承載StackNavigation導航器,那這個導航器是什麼?
代碼裏面分兩個部分,第一個部分是包含全部界面的組件集合,另外一個部分是聲明咱們初始化的界面組件是哪個,看到這裏咱們應該知道了,範例中咱們聲明瞭兩個界面組件,Home 和 Details ,而且聲明初始化的路由名字是Home,因此打開界面的首先會進入Home界面,其實這有點像註冊路由同樣,咱們要把設計到的界面組件註冊到路由裏面,這樣咱們纔會navigation的時候纔會找獲得它。
該範例運行結果以下:
咱們看到當前的界面確實是Home Screen,而且點擊按鈕會打開Details界面,返回箭頭會直接返回Home,這只是一個簡單的跳轉邏輯,咱們須要作一些更改,怎麼改呢?咱們能夠嘗試一下在Details Screen裏面再放入一下Button,細心地朋友看到了上面代碼中咱們已經加入了,而且跳轉的時候咱們仍是跳轉到當前而且是push的,效果會怎麼樣呢,我已經給了註釋,結果倒是會從新打開這個Derails界面,此時的棧中就兩個Details實例了,這是否是跟Android的啓動模式類似呢,安卓默認的啓動模式standard就是這樣的效果,可是若是咱們不用push,仍是navigation的話,結局是什麼樣呢?結果就是沒有任何反應,那Android的啓動模式能夠作到相似的效果,惟一的不一樣點就是Android會走特定的生命週期方法。
堆棧導航器提供的標題將在能夠從活動屏幕返回時自動包含後退按鈕(若是導航堆棧中只有一個屏幕,則沒有任何內容能夠返回,所以沒有返回鍵)。
有的時候咱們但願可以主動觸發此行爲,咱們就可使用this.props.navigation.goBack();
。
class DetailsScreen extends React.Component { render() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Details Screen</Text> <Button title="Go to Details... again" onPress={() => this.props.navigation.push('Details')} /> <Button title="Go to Home" onPress={() => this.props.navigation.navigate('Home')} /> <Button title="Go back" onPress={() => this.props.navigation.goBack()} /> </View> ); } }
這裏面咱們發現回到Home咱們是直接navigation的,看看效果是否是跟Android的啓動模式SingleTask很相似呢,對,就是這樣,那咱們也能夠另一種方式也能夠達到這個效果navigation.popToTop()。
導航跳轉咱們搞定了,接下來咱們要傳遞參數,界面與界面之間傳遞參數是必不可少的操做。
傳遞參數是在咱們navigation的時候多加一個參數便可,this.props.navigation.navigate('routeName',{key:value}),格式就是這樣,咱們看一下代碼:
這裏咱們只是傳遞了兩個參數itemId和otherParam,那在DetailsScreen咱們怎麼去接收呢,代碼以下:
其實方式很簡單,跟map的操做方式很像。
若是你想經過道具直接訪問params(例如。this.props.itemId
)而不是this.props.navigation.getParam
,那麼你可使用社區開發的react-navigation-props-mapper包。
如今看咱們的界面是否是很枯燥無味,導航欄上面什麼也沒有,這個時候咱們能夠添加咱們本身的界面標題。
這個時候咱們須要使用到navigationOptions這個屬性來配置標題顯示。
如上圖所示的配置便可,而後運行咱們會發現標題有了:
createStackNavigator 默認狀況下使用平臺約定,所以在iOS上標題將居中,而在Android上它將是左對齊的。