react-navigation是一個來源於react社區的導航解決方案。 以我一個月資深的react開發經驗來看,說是react-native
開發app必備庫之一絕不過度。html
在開發過程當中,不一樣頁面由於不一樣的業務需求會有不一樣的頭部(header),這篇文章針對幾種經常使用我遇到過的各類header提供對應的react-navigation
解決方案。react
底部tab對app來講是十分常見的需求。react-navigation
也提供了相應的API來建立底部tab: createBottomTabNavigator
git
如何定製tab頁的header呢? 咱們分狀況討論:github
很簡單,無需額外的配置。react-native
第一時間可能會想到的是在createBottomTabNavigator
中對每一個頁面的navigationOptions
對象設置header
爲null。app
createBottomTabNavigator( { Home: { screen: Home, navigationOptions: { header: null // 無效!! } } } )
但實際上createBottomTabNavigator
中的navigationOptions
對象是不接受header
參數的,至少文檔中沒寫。官方文檔函數
解決方式:在根級導航中設置。spa
const AppNavigator = createStackNavigator( { Main: { screen: TabNavigator, // TabNavigator就是經過createBottomTabNavigator建立的底部導航 navigationOptions: { header: null } } // other pages } )
其實navigator是能夠互相嵌套的。 就像上面的例子中,Main路由的頁面是createBottomTabNavigator
建立的底部導航。同理,底部導航中某個tab的頁面也能夠是導航頁。有點繞,仍是看代碼code
const bottomTabNavigator = createBottomTabNavigator( { Home: { screen: Home, navigationOptions: { // some options } }, User: { // user頁要"頭"~ screen: createStackNavigator( { User: { screen: User, navigationOptions: { header: customHeader } } } ) } } ) const appNavigator = createStackNavigator( { Main: { screen: bottomTabNavigator, navigationOptions: { header: null // 這裏要將bottomTabNavigator的header設爲null } }, Other: { screen: Other } } )
由於默認狀況下bottomTabNavigator會有一個本身的header,而user咱們又建立了一個帶header的路由頁面,因此咱們將Main
路由(bottomTabNavigato)的header設爲null,若是不設置的,頁面會有2個header哦,小夥伴可自行嘗試。htm
若是我只有某個tab頁不要header,咋辦?
仍是從navigationOptions
入手,navigationPptions屬性能夠是一個接受navigation
對象,返回一個新對象的函數。
關於navigation
對象,能夠看官方文檔
這裏咱們用到了該對象的state
屬性。
如今咱們有以下導航配置:
const TabNavigator = createBottomTabNavigator( { Home: { screen: Home, navigationOptions: { title: '首頁' } }, Phone: { screen: createStackNavigator( { Phone: { screen: Phone, navigationOptions: ({ navigation }) => ( { // phoneHeader爲自定義React組件 header: <PhoneHeader navigation={navigation}/> } ) } } ), navigationOptions: { tabBarVisible: false, title: '機型' } }, User: { screen: User, navigationOptions: { title: '個人' } } } )
上面代碼建立了包含3個tab的底部導航,其中phone
的header是定製的。接下去咱們要作的是配置在appNavigator
中配置TabNavigator
的navigation
屬性,根據不一樣的路由使用不一樣的header(即當處在home頁或是user頁時候,使用默認的header,當處在phone頁面時,移除header。
爲何是移除header?
由於phone頁面已經自定義了header,咱們只需移除外層TabNavigator的header便可。若是否則,會有2個header(TabNavigator和phone2個header)。這個上面已經提到。另外,也能夠將定製的header配置在appNavigator
中TabNavigator
的navigation
屬性裏。(未驗證,可自行嘗試。)
const AppNavigator = createStackNavigator( { Main: { screen: TabNavigator, navigationOptions: ({ navigation }) => { const titleMap = { Home: '首頁', User: '個人' } // 根據路由的順序以及路由名定義title const result = { title: titleMap[navigation.state.routes[navigation.state.index].routeName], headerTitleStyle: { fontWeight: '600', color: color.gray_1, fontSize: px2p(18) }, headerBackTitle: null } // 在配置TabNavigator時,phone頁面是第一個定義的(zero-indexed)。 // 因此當index爲1的時,header設爲null // 或者將header設爲自定義header,對應修改TabNavigator中phone。 if (navigation.state.index === 1) { result.header = null result.headerTransparent = true } return result } }, ...pages // 其餘頁面 }, { initialRouteName: 'Main' } )
至此,這篇水文也寫的差很少了。
下篇文章(若是有)我會寫一下關於自定義header的部分。
主要是headerRight部分,好比淘寶京東的商品詳情頁右上角會有個按鈕,點擊彈出菜單欄。
Thanks for reading~