上一篇文章講了如何用react-navigation
建立各類自定義頭部(header)。css
這篇水文講一下如何實現header右部的菜單項。暫時只支持IOS,緣由後文會說明,並給出一些未論證的想法react
參考京東商品詳情頁右上角的交互。android
自定義頭部右側很簡單,配置navigationOptions
的headerRight
選項,傳入咱們的自定義組件便可。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
isMenuVisible
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(之前用的是另一個方法)。 究其緣由是RN在Android端不支持顯示超出父元素部分的內容,用css的話來說就是overflow: hidden
並且只能是hidden。佈局
這方面的呼聲也不低,期待官方能解決吧。
HeaderMenu
部分寫在對應的組件中。在配置HeaderRight時,經過一個閉包保存菜單項的狀態。每次點擊經過navigation的setParams
API來對指定頁面傳遞這個狀態。
這個方法也有缺陷,若是header不是透明的,則菜單項會被header覆蓋,就算緊貼header也會略顯難看。 以及佈局方便須要大改動,而且很麻煩。提一點:菜單項的position是absolute。
react-native-view-overflow
這是我剛搜到的解決方案,經過包裹一層組件來達到顯示超出部分的內容的效果。
import ViewOverflow from 'react-native-view-overflow'; <ViewOverflow> <ComponentToEnableOverflow /> </ViewOverflow>
在咱們這個情景下,就要改寫默認的header組件,小夥伴能夠自行嘗試。(丟連接就跑,真刺激)
源代碼能夠在GitHub上看到。
效果圖: