React Native 摺疊功能的實現及安卓踩坑筆記
阿新 • • 發佈:2018-11-29
市面上有相應的外掛 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