React Native Animated循环图片动画闪烁异常如何解决

问题描述
需要实现固定节奏的循环淡入淡出动画,单轮动画的预期逻辑:
- 图片淡入,耗时0.5秒
- 图片保持完全可见状态2.5秒
- 图片淡出,耗时0.5秒
- 图片保持完全不可见状态2.5秒
实际运行时动画不符合预期,图片会出现非正常的闪烁问题。
原问题代码
const fadeAni = useRef<Animated.Value>(new Animated.Value(0)).current; useEffect(() => { Animated.loop( Animated.sequence([ Animated.timing(fadeAni, { toValue: 1, duration: 500, useNativeDriver: true, }), Animated.delay(2500), Animated.timing(fadeAni, { toValue: 0, duration: 500, useNativeDriver: true, }), Animated.delay(2500), ]), ).start() }, []) return ( <Animated.View style={{ opacity: fadeAni }}> <ImageBackground source={imageSource} style={styles.area}> </ImageBackground> </Animated.View> );
问题原因
闪烁的根源是Animated.loop的默认行为和原生驱动的时序差:
Animated.loop默认配置中resetBeforeIteration为true,每轮循环启动前,会强制把动画值硬重置为初始值(即初始化时的0)- 虽然这段代码单轮动画结束时,
fadeAni本身就已经是0,但这个硬重置操作是独立于动画序列执行的。开启useNativeDriver: true时,JS层指令和原生动画队列的执行存在一帧左右的时序差,会导致原生层渲染出现透明度跳变,也就是观察到的非正常闪烁。
修复方法
当前动画序列每轮执行结束时,值已经回到初始值0,不需要loop执行自动重置,给Animated.loop传入配置项关闭自动重置即可。
修复后完整代码
const fadeAni = useRef<Animated.Value>(new Animated.Value(0)).current; useEffect(() => { Animated.loop( Animated.sequence([ Animated.timing(fadeAni, { toValue: 1, duration: 500, useNativeDriver: true, }), Animated.delay(2500), Animated.timing(fadeAni, { toValue: 0, duration: 500, useNativeDriver: true, }), Animated.delay(2500), ]), { resetBeforeIteration: false // 关闭每轮循环前的强制值重置 } ).start() }, []) return ( <Animated.View style={{ opacity: fadeAni }}> <ImageBackground source={imageSource} style={styles.area}> </ImageBackground> </Animated.View> );
如果后续调整动画逻辑,单轮结束时动画值和初始值不一致,不能直接关闭重置的话,可以把序列中的
Animated.delay替换为相同时长、toValue等于当前阶段目标值的Animated.timing,保证整个动画队列连续,也能避免硬重置带来的闪烁问题。
内容的提问来源于stack exchange,提问作者nayounsang
相关产品推荐
相关产品推荐

