RN Animated.FlatList调用ScrollToIndex在Android出现闪烁问题
React Native FlatList无限轮播滑动跳转闪烁问题
我用FlatList实现了一个基于有限数据集的无限轮播组件,逻辑是滑动到末尾时通过ScrollToIndex方法跳转到开头,滑动到开头时跳转到末尾。但在Android平台,从最后一张横幅跳转至第一张时,ScrollToIndex会引发奇怪的闪烁现象,iOS也存在轻微不稳定的问题。
相关代码如下:
const Carousel = () => { const [activeBanner, setActiveBanner] = useState(0); const scrollX = useRef(new Animated.Value(0)).current; const listRef = useRef<RNFlatList>(null); const goToIndex = (index: number, animated: boolean) => { listRef.current?.scrollToIndex({ index, animated, }); }; const handleScroll = (event: any) => { const { contentOffset } = event.nativeEvent; const currentIndex = Math.floor((contentOffset.x - 50) / FULL_BANNER_WIDTH); if ( currentIndex >= banners.length && contentOffset.x >= ACTIVE_BANNER_WIDTH * (banners.length + 1) - 20 ) { goToIndex(1, false); } else if (currentIndex <= 0 && contentOffset.x <= 0) { goToIndex(banners.length, false); } } const itemLayout = (_data: any, index: number) => ({ length: FULL_BANNER_WIDTH, offset: FULL_BANNER_WIDTH * index, index: index, }); const onViewableItemsChangedHandler = (info: any) => { if (info.viewableItems.length > 0) { setActiveBanner(info.viewableItems[0].index - 1); } else { setActiveBanner(0); } }; const viewConfigRef = React.useRef([ { viewabilityConfig: { waitForInteraction: false, itemVisiblePercentThreshold: 100, minimumViewTime: 0, }, onViewableItemsChanged: onViewableItemsChangedHandler, }, ]); const flatlistMemo = React.useMemo(() => { return ( <Animated.FlatList decelerationRate={0.9} disableIntervalMomentum={true} disableScrollViewPanResponder={true} snapToInterval={FULL_BANNER_WIDTH} horizontal={true} showsHorizontalScrollIndicator={false} ref={listRef} data={renderItem} renderItem={renderItems} keyExtractor={keyExtractor} onScroll={Animated.event( [{ nativeEvent: { contentOffset: { x: scrollX } } }], { useNativeDriver: true, listener: event => handleScroll(event) } )} scrollEventThrottle={16} onScrollToIndexFailed={onScrollFail} getItemLayout={itemLayout} onScrollBeginDrag={() => setIsDragging(true)} onScrollEndDrag={() => setIsDragging(false)} initialScrollIndex={1} contentContainerStyle={[ styles.flatListContainer, { marginLeft: -HIDDEN_BANNER_PORTION, }, ]} viewabilityConfigCallbackPairs={viewConfigRef.current} /> ); }, [renderItem]); return ( <View>{flatlistMemo}</View> ) }
我已经尝试过以下解决方法,但都没解决问题:
- 移除用于追踪当前横幅的
setState - 添加/移除FlatList的memoization处理
- 调整
keyExtractor - 移除动画效果
- 配置
windowsize等参数 - 改用ScrollView/ScrollTo方法
内容的提问来源于stack exchange,提问作者tammi
相关产品推荐
相关产品推荐

