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上看到。

效果圖:
效果圖

相關文章
相關標籤/搜索