React Native開發(fā)有一點(diǎn)挺友好的,就是文檔寫的比較清楚詳細(xì),而且有中文網(wǎng)。中文網(wǎng)不只是把英語翻譯成中文,而在需要注意的地方加了一些譯注。最好不要忽略這些譯注,不然新手很容易掉坑里,這也是我的親身經(jīng)驗(yàn)。
React Native現(xiàn)有幾個(gè)導(dǎo)航組件,但是導(dǎo)航庫react-navigation是社區(qū)主推使用的導(dǎo)航庫。
如果你剛開始接觸,那么直接選擇React Navigation就好。如果你只針對iOS平臺開發(fā),并且想和系統(tǒng)原生外觀一致,那么可以選擇NavigatorIOS。
功能

這個(gè)Demo的主要頁面如上所示。導(dǎo)航的邏輯:
進(jìn)入首頁,導(dǎo)航欄的右側(cè)包含一個(gè)按鈕,點(diǎn)擊可以調(diào)用系統(tǒng)自帶瀏覽器。
a.選擇注冊,跳轉(zhuǎn)到注冊頁面。
b.如果已有賬號,則點(diǎn)擊登錄跳轉(zhuǎn)到登錄頁面。注冊成功自動跳轉(zhuǎn)到登錄頁面。
a.此時(shí)可以選擇用剛注冊的賬戶登錄;
b.或者點(diǎn)擊導(dǎo)航欄的返回鍵回到首頁。登錄成功自動跳轉(zhuǎn)到包含兩個(gè)標(biāo)簽頁的頁面。
選擇“賬戶”,點(diǎn)擊注銷,可以直接跳轉(zhuǎn)回首頁。

整個(gè)過程不考慮cookie,著重考慮導(dǎo)航欄控制屏幕之間跳轉(zhuǎn)。
實(shí)現(xiàn)
這個(gè)邏輯是很基礎(chǔ)很簡單的,用到了 React Navigation庫的三個(gè)組件:
-
StackNavigator:基礎(chǔ)。使用堆棧儲存導(dǎo)航信息(新的屏幕信息保存在堆棧的頂部)。 -
NavigationActions:各種跳轉(zhuǎn)方法。 -
TabNavigator:標(biāo)簽頁的導(dǎo)航欄。
導(dǎo)航結(jié)構(gòu)
能夠跳轉(zhuǎn)到的頁面都要加到StackNavigator初始化中。
StackNavigator(RouteConfigs, StackNavigatorConfig)
第一個(gè)參數(shù)是Route配置,第二個(gè)參數(shù)是統(tǒng)一的導(dǎo)航欄樣式等的配置。在Route配置中,可以單獨(dú)配置某個(gè)頁面的導(dǎo)航欄。比如Tabs頁面,因?yàn)樘砑恿说撞繕?biāo)簽頁導(dǎo)航欄,不需要頂部的導(dǎo)航欄了,所以設(shè)置navigationOptions的header,從而隱藏這個(gè)頁面的頂部導(dǎo)航欄。
//App.js
//頂部導(dǎo)航欄
export const App = StackNavigator({
Home: {screen: HomeScreen}, //首頁
Register: {screen: RegisterScreen}, //注冊
Login: {screen: LoginScreen}, //登錄
Tabs: { //登錄之后的標(biāo)簽頁
screen: BottomTab,
navigationOptions:{
header: null //隱藏頂部導(dǎo)航欄
}
},
},{
navigationOptions: { //配置頂部導(dǎo)航
headerTitleStyle: { //導(dǎo)航欄文字的樣式
fontSize: 18,
color: '#b2b2b2',
},
// headerBackTitleStyle: { //‘返回’文字的樣式
// color: '#b2b2b2'
// },
headerStyle: { //導(dǎo)航欄的樣式
backgroundColor: '#343434',
borderBottomColor: '#f5a623',
borderBottomWidth: 1
},
}
});
//注冊組件。TestProject是APP的名稱。
AppRegistry.registerComponent('TestProject', () => App);
跳轉(zhuǎn)到某個(gè)頁面
如果我們要跳轉(zhuǎn)到StackNavigator中的某個(gè)頁面,可以調(diào)用this.props.navigation提供的navigat方法。應(yīng)用中的每個(gè)Screen組件都接收到一個(gè)navigation的prop。詳情可閱讀:
https://reactnavigation.org/docs/navigators/navigation-prop。
const { navigate } = this.props.navigation;
navigate('Tabs',{username:this.state.username}) //可傳遞參數(shù)
首頁>注冊>登錄>返回主頁
注冊成功之后自動跳轉(zhuǎn)到登錄頁,這時(shí)候點(diǎn)擊返回的,怎么直接返回主頁,而不是返回上一級的注冊頁?
我的方法是,在注冊成功之后,使用NavigationActions的reset方法重置導(dǎo)航的堆棧信息。只保留首頁和當(dāng)前的登錄頁。
//app.js
//注冊之后自動跳轉(zhuǎn)到登錄頁面中,并且重置導(dǎo)航stack,使得不能返回注冊頁面
export const afterRegisterAction = NavigationActions.reset({
index: 1, //1表示當(dāng)前調(diào)度到Login頁面
actions: [ //新的導(dǎo)航操作歷史
NavigationActions.navigate({ routeName: 'Home'}),
NavigationActions.navigate({ routeName: 'Login'}),
]
})
使用時(shí):
import {afterRegisterAction} from '../App'
......
this.props.navigation.dispatch(afterRegisterAction) //跳轉(zhuǎn)到登錄頁面
在賬戶頁面注銷回到首頁也是這個(gè)原理:
//回到首頁,且清空stack中的其他的導(dǎo)航記錄。
export const resetToHomeAction = NavigationActions.reset({
index: 0, //對應(yīng)actions中的index。指定當(dāng)前頁面。
actions: [ //替換之后的導(dǎo)航記錄
NavigationActions.navigate({ routeName: 'Home'})
]
})
底部標(biāo)簽頁導(dǎo)航
使用TabNavigator制作標(biāo)簽頁導(dǎo)航。清晰明了直接上代碼:
import {Text} from 'react-native';
import { TabNavigator } from "react-navigation";
import AssetListScreen from './AssetList'
import AccountScreen from './Account'
const BottomTab = TabNavigator({
AssetList: { screen: AssetListScreen}, //資產(chǎn)標(biāo)簽頁
Account: { screen: AccountScreen}, //賬號標(biāo)簽頁
},
{
tabBarPosition: 'bottom', //android默認(rèn)的TabNavigator是在上方。在StackNavigator下面。所以需要特意指定。
animationEnabled: true, //標(biāo)簽切換時(shí)的動畫
tabBarOptions: {
activeTintColor: '#f5a623', //active時(shí)標(biāo)簽中文字和Icon的顏色
labelStyle: { //標(biāo)簽文字的樣式
fontSize: 12
},
indicatorStyle:{ //android標(biāo)簽下劃線的樣式。注意這里不是設(shè)置color。
backgroundColor: '#f5a623'
},
style: { //整體標(biāo)簽欄的樣式
backgroundColor: '#343434',
},
showIcon: true, //android上默認(rèn)不顯示icon。所以要特別設(shè)定。
}
}
);
export default BottomTab;
導(dǎo)航欄中的按鈕
在每個(gè)Screen組件的內(nèi)部,可以設(shè)置navigationOptions來修改這一頁的導(dǎo)航欄,比如設(shè)置標(biāo)題等。
//Home.js
import Button from 'react-native-button' //使用react-native-button組件。其他按鈕組件:https://js.coach/react-native
export default class HomeScreen extends React.Component {
static navigationOptions = {
title: 'ReactNativeDemo',
headerRight: ( //定義導(dǎo)航欄右側(cè)的按鈕
<Button
style={{fontSize:12, color:'#fff'}}
containerStyle={{marginRight:10,height:30, width:50, overflow:'hidden', borderRadius:4, backgroundColor: '#343434', borderColor:'#b2b2b2', borderWidth:1, justifyContent:'center'}}
onPress={()=>contact()}
>
聯(lián)系
</Button>),
};
}
...
參考鏈接
- React Native 中文網(wǎng),使用導(dǎo)航器跳轉(zhuǎn)頁面:http://reactnative.cn/docs/0.48/navigation.html#content
- Hello Mobile Navigation: https://reactnavigation.org/docs/intro/
React Navigation的官方文檔,例子挺多而且詳細(xì)。入門必看。要定制導(dǎo)航欄的話,就仔細(xì)看看API中有沒有對應(yīng)的屬性。畢竟例子不能全都覆蓋到。