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~

相关文章
相关标签/搜索