react-navigation使用小記

react-navigation 使用小記

平常廢話

react-navigation是一個來源於react社區的導航解決方案。 以我一個月資深的react開發經驗來看,說是react-native開發app必備庫之一絕不過度。html

在開發過程當中,不一樣頁面由於不一樣的業務需求會有不一樣的頭部(header),這篇文章針對幾種經常使用我遇到過的各類header提供對應的react-navigation解決方案。react

我是正文

底部tab對app來講是十分常見的需求。react-navigation也提供了相應的API來建立底部tab: createBottomTabNavigatorgit

如何定製tab頁的header呢? 咱們分狀況討論:github

全部tab頁都要header

很簡單,無需額外的配置。react-native

全部tab頁都不要header

第一時間可能會想到的是在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
  }
)

只有某個tab要header

其實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 or 須要定製header

若是我只有某個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中配置TabNavigatornavigation屬性,根據不一樣的路由使用不一樣的header(即當處在home頁或是user頁時候,使用默認的header,當處在phone頁面時,移除header

爲何是移除header?

由於phone頁面已經自定義了header,咱們只需移除外層TabNavigator的header便可。若是否則,會有2個header(TabNavigator和phone2個header)。這個上面已經提到。另外,也能夠將定製的header配置在appNavigatorTabNavigatornavigation屬性裏。(未驗證,可自行嘗試。)

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'
  }
)

END

至此,這篇水文也寫的差很少了。

下篇文章(若是有)我會寫一下關於自定義header的部分。

主要是headerRight部分,好比淘寶京東的商品詳情頁右上角會有個按鈕,點擊彈出菜單欄。

Thanks for reading~

相關文章
相關標籤/搜索