react-navigation使用小记(2) 自定义header菜单项

使用react-navigation实现headerRight菜单组件。

平常废话

上一篇文章讲了如何用react-navigation建立各类自定义头部(header)。css

这篇水文讲一下如何实现header右部的菜单项。暂时只支持IOS,缘由后文会说明,并给出一些未论证的想法react

正文

写的啥?

参考京东商品详情页右上角的交互。android

怎么实现

自定义头部右侧很简单,配置navigationOptionsheaderRight选项,传入咱们的自定义组件便可。git

const AppNavigator = createStackNavigator(
  {
    Home: {
      screen: Home,
      navigationOptions: {
        title: '首页'
      }
    },
    GoodDetail: {
      screen: GoodDetail,
      navigationOptions: ({navigation}) => ({
        headerTransparent: true,
        headerStyle: {
          borderBottomWidth: 0,
        },
        headerTintColor: '#313131',
        shadowOpacity: 0,
        headerRight: <HeaderRight navigation={navigation}/>
      })
    }
  }
)

HeaderRight怎么写?分析一哈:github

  1. 样子是"三个点":用图片吧。
  2. 点它要有反应: 套一个<TouchableOpacity>吧
  3. 点完展示菜单:自身维护一个状态isMenuVisible
  4. 暂时就那么多,先写写看。
class HeaderRight extends Component {
  constructor() {
    super()
    this.state = {
      isMenuVisible: false
    }
  }

  toggleMenu = () => {
    this.setState((prevState) => {
      isMenuVisible: !prevState.isMenuVisible
    })
  }

  render() {
    return (
      <TouchableOpacity onPress={this.toggleMenu}>
        <Image source={require('/path/to/image')}/>
        {
          isMenuVisible && (
            <HeaderMenu 
              navigation={this.props.navigation}
            />
          )
        }
      </TouchableOpacity>
    )
  }
}

哦了,HeaderMenu是一个无状态组件,也就是菜单项,样式根据业务自行写咯~segmentfault

写完以后好像没什么问题的,可是若是你滚动你的页面(若是你的页面能够滚动),你会发现菜单项不会本身消失。react-native

这怎么行!闭包

解决方法: 咱们给HeaderMenu外层包裹一个View,宽高为容器宽高,绝对定位,使其充满整个屏幕。再在外层包裹一个TouchableWithoutFeedback,注册onPress,点击时执行隐藏菜单的函数,而这个函数能够定义在HeaderRight中,经过props传递给HeaderMenu函数

为何只支持IOS

其实我是在写这篇文章的时候才发现,我这个方法只支持IOS(之前用的是另一个方法)。 究其缘由是RN在Android端不支持显示超出父元素部分的内容,用css的话来说就是overflow: hidden并且只能是hidden。布局

这方面的呼声也不低,期待官方能解决吧。

Android下解决方法的设想

HeaderMenu部分写在对应的组件中。

在配置HeaderRight时,经过一个闭包保存菜单项的状态。每次点击经过navigation的setParamsAPI来对指定页面传递这个状态。

这个方法也有缺陷,若是header不是透明的,则菜单项会被header覆盖,就算紧贴header也会略显难看。 以及布局方便须要大改动,而且很麻烦。提一点:菜单项的position是absolute。

采用开源的方案(未验证)

react-native-view-overflow
这是我刚搜到的解决方案,经过包裹一层组件来达到显示超出部分的内容的效果。

import ViewOverflow from 'react-native-view-overflow';

<ViewOverflow>
    <ComponentToEnableOverflow />
</ViewOverflow>

在咱们这个情景下,就要改写默认的header组件,小伙伴能够自行尝试。(丢连接就跑,真刺激)

结尾

源代码能够在GitHub上看到。

效果图:
效果图

相关文章
相关标签/搜索