[RN]ScrollView嵌套FlatList在安卓上无法执行FlatList的滚动

轩辕瑞
2023-12-01

项目里在横向的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>

但是这种方式还是有些小问题的,如果按下和释放动作之间相隔的时间太短,就没有用了

参考链接: https://cloud.tencent.com/developer/article/1093733

 类似资料: