React Native 摺疊功能的實現及安卓踩坑筆記 原

市面上有相應的插件 react-native-collapsible, 但它在摺疊狀態底部有莫名其妙的空白,且有很多bug未解決, 於是自己試着實現了一個簡版。

基礎結構

<View style={S.container}>
  <View style={{flex: 1}}>
    <View style={S.content}
      onLayout={this.onContentLayout}>
      { this.props.children }
    </View>
  </View>
</View>

const S = StyleSheet.create({
  container: {
    overflow: 'hidden'
  },
  content: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0
  }
})

我們需要能動態控制顯示高度,會用到overflow:hidden,而默認狀態是摺疊的,因此,爲了獲取實際內容的真實高度(不固定),需加兩層嵌套,以便通過onLayout方法提前得到展開後的高度。

這是開啓動畫的前提。

動畫的實現

這裏介紹兩種方式

Animated Component

這是我常用的技巧。首先把container裏面的元素用Animated.View封裝:

<Animated.View style={{ height: this.state.height }}>
  <View style={{flex: 1}}>
    ...
  </View>
</Animated.View>

其中height初值爲new Animated.Value(0),數值0表示完全摺疊。

然後當展開時,給height應用動畫即可:

Animated.timing(
  this.state.height,
  {
    toValue: newHeight,
    duration: this.props.duration || 300,
    easing: this.props.easing || Easing.linear
  }
).start()

這裏newHeight爲新的高度值,比如第一步中通過onLayout得到的真實高度。

反之亦然,摺疊時,再設爲0即可。

LayoutAnimation

這是從reactnativecode.com上學到的技巧,原作者不詳。

這種方法不需要再次封裝,代碼相對簡潔得多。這回我們直接在container上設置height

<View style={[ S.container, { height: this.state.height } ]}>
  ...
</View>

然後當摺疊或展開時,設定動畫並更新高度值:

LayoutAnimation.configureNext( LayoutAnimation.Presets.easeInEaseOut )

this.setState({ height: newHeight })

注意事項

在安卓機上,需要手動開啓動畫:

if ( Platform.OS === 'android' ) {
  UIManager.setLayoutAnimationEnabledExperimental(true)
}

踩坑

安卓下內容溢出

儘管設置了overflow:hidden,安卓下內容仍然會溢出一部分,然後和下方的內容層疊了,醜爆。

不能說overflow無效,但又不完全符合預期,試了多種方法包括改結構,均無效,太認人沮喪了。

爲了方便調試,就加了背景色,居然好了。莫名其妙的就好了!

所以解決方法是——設定背景色。

over

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章