项目里在横向的ScrollView里套了一个react-native-swiper-flatlist写的图片轮播,在安卓上ScrollView和FlatList嵌套,滚动事件只会在最外层执行, ios上正常。
使用PanResponder来解决,写成函数组件如下:
在父组件:
const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => (console.warn('wrap start responder')),
onStartShouldSetPanResponderCapture: (evt, gestureState) => (console.warn('wrap start responder capture')),
onMoveShouldSetPanResponder: (evt, gestureState) => (console.warn('wrap move responder')),
onMoveShouldSetPanResponderCapture: (evt, gestureState) => (console.warn('wrap move responder capture')),
onPanResponderGrant: (evt, gestureState) => { },
onPanResponderMove: (evt, gestureState) => { },
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => { },
onPanResponderTerminate: (evt, gestureState) => { },
onShouldBlockNativeResponder: (evt, gestureState) => {
// only android
return false
}
})
).current;
const lockWrapScroll = () => {
scrollRef.current && scrollRef.current.setNativeProps({
scrollEnabled: false
})
}
const unlockWrapScroll = () => {
scrollRef.current && scrollRef.current.setNativeProps({
scrollEnabled: isOnEditingInput || isFullScreen ? false : true
})
}
...
<View style={{ flex: 1 }} {...(Platform.OS === 'android' ? panResponder.panHandlers : {})}>
<ScrollView ref={(ref) => { scrollRef.current = ref;}}>
...
</ScrollView>
</View>
然后在子组件,因为每个图片外层都用了TouchableOpacity组件包住,可以用onPressIn和onPressOut事件来执行锁定和解锁外层的滚动
<SwiperFlatList
showPagination
autoplay={true}
autoplayLoop={true}
paginationStyleItem={customerStyles.pagination}
paginationStyleItemActive={customerStyles.activePagination}
PaginationComponent={props.isNormal ? NormalPagination : CustomPagination}
{...props}>
{banner.map((item, index) => {
return (
<TouchableOpacity
key={index}
onPressIn={() => {
Platform.OS === 'android' && lockWrapScroll && lockWrapScroll()
}}
onPressOut={() => {
Platform.OS === 'android' && unlockWrapScroll && unlockWrapScroll()
}}
>
......
</TouchableOpacity>
);
})}
</SwiperFlatList>
但是这种方式还是有些小问题的,如果按下和释放动作之间相隔的时间太短,就没有用了