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

市面上有相應的插件 react-native-collapsible, 但它在摺疊狀態底部有莫名其妙的空白,且有不少bug未解決, 因而本身試着實現了一個簡版。react

基礎結構

<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方法提早獲得展開後的高度。android

這是開啓動畫的前提。react-native

動畫的實現

這裏介紹兩種方式flex

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表示徹底摺疊。this

而後當展開時,給height應用動畫便可:插件

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

這裏newHeight爲新的高度值,好比第一步中經過onLayout獲得的真實高度。調試

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

LayoutAnimation

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

這種方法不須要再次封裝,代碼相對簡潔得多。這回咱們直接在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

相關文章
相關標籤/搜索