RN的幾種嵌套滑動總結
安卓常用的幾種嵌套滑動的組合:
ScrollView嵌套WebView
ScrollView需要高度才能渲染,直接嵌套會導致空白。
通過插入js的方式,在載入WebView的時候先傳回WebView高度,::動態設置高度::
const BaseScript =
`
(function () {
var height = null;
function changeHeight() {
if (document.body.scrollHeight !== height) {
height = document.body.scrollHeight;
if (window.postMessage) {
// 如果是引用了react-native-webView
// 將window.postMessage替換成window.ReactNativeWebView.postMessage即可
window.postMessage(JSON.stringify({
type: 'setHeight',
height: height,
}))
}
}
}
setInterval(changeHeight, 1000);
} ())
`;
onMessage = (event) => {
try {
const action = JSON.parse(event.nativeEvent.data);
if (action.type === 'setHeight' && action.height > 0) {
this.setState({
height: action.height,
});
}
} catch (error) {
console.log(error);
}
}
<ScrollView>
<WebView
originWhitelist={['*']}
style={{ height: this.state.height, width: SCREEN_WIDTH }}
automaticallyAdjustContentInsets={false}
injectedJavaScript={BaseScript}
decelerationRate="normal"
scalesPageToFit
javaScriptEnabled
domStorageEnabled
scrollEnabled={false}
onMessage={this.onMessage}
/>
</ScrollView>
ScrollView嵌套FlatList
ScrollView嵌套FlatList,還想實現FlatList的下拉刷新和上拉加載,可以配合rn的手勢系統PanResponder
涉及滑動的部分有ScrollView的scrollEnable屬性,onScrollEndDrag方法,react-native組件PanResponder,及FlatList自己的下拉加載。
ScrollView嵌套FlatList,使用onScrollEndDrag方法監聽滑動的位置,配合PanResponder手勢。
當scrollOffset等於0時,手勢下拉,則禁用ScrollView的滑動(scrollView的scrollEnable),此時可以實現flatList的自己的下拉刷新。
componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
},
onPanResponderMove: (evt, gestureState) => {
if (gestureState.dy < 0 && !this.state.enableScrollViewScroll) {
this.setState({
enableScrollViewScroll: true,
});
}
if (this.state.scrollOffset === 0 && gestureState.dy > 0 && this.state.enableScrollViewScroll) {
this.setState({
enableScrollViewScroll: false,
});
}
},
onPanResponderRelease: (evt, gestureState) => {
},
onPanResponderTerminate: (evt, gestureState) => {
},
});
}
當scrollOffset和列表高度之和大於等於內容高度時,scrollView滑動到底部,調用分頁的接口,實現上拉加載。
handleScrollEnd = (event) => {
const contentHeight = event.nativeEvent.contentSize.height;
const scrollViewHeight = event.nativeEvent.layoutMeasurement.height;
const scrollOffset = event.nativeEvent.contentOffset.y;
this.setState({
scrollOffset,
})
if (scrollOffset < 5) {
this.setState({
enableScrollViewScroll: false,
});
}
console.log('contentHeight', contentHeight);
console.log('scrollViewHeight', scrollViewHeight);
console.log('scrollOffset', scrollOffset);
console.log('是否滑動到底部', scrollOffset + scrollViewHeight >= contentHeight);
console.log('內容高度是否大於列表高度', contentHeight >= scrollViewHeight);
const isEndReached = scrollOffset + scrollViewHeight >= contentHeight; // 是否滑動到底部
const isContentFillPage = contentHeight >= scrollViewHeight; // 內容高度是否大於列表高度
// 實現下拉加載
if (isContentFillPage && isEndReached) {
// 獲取分頁數據的方法
}
};