React Native Animated View背景色动画设置报错:原生动画模块不支持backgroundColor属性
Hey,这个报错我太熟了!问题核心很简单:你开启了useNativeDriver: true,但React Native的原生动画模块压根不支持backgroundColor这类样式属性。原生驱动只对transform(平移、旋转这些)和opacity这类能在原生层面高效处理的属性友好,像背景色这种需要更新视图样式的,只能交给JS驱动来搞定。
怎么修复?我给你整理了两步:
- 拆分动画值:把需要原生驱动的(比如你的平移、旋转、透明度)和需要JS驱动的(背景色)分成两个独立的
Animated.Value,这样两边动画互不干扰,还能保留原生驱动的性能优势。 - 针对性关闭原生驱动:给背景色的动画单独设置
useNativeDriver: false,其他动画继续用原生驱动就行。
下面是修改后的完整代码,我还帮你修正了一个小问题——你原来的动画toValue: 0,这样inputRange [0,100]永远停在初始值,颜色根本不会变,我改成了toValue:100,这样动画才会正常跑起来:
import React, {useEffect, useRef} from 'react'; import {Animated} from 'react-native'; export default function Welcome(props) { // 拆分两个动画值,分别处理不同类型的动画 const transformOpacityAnim = useRef(new Animated.Value(0)).current; const backgroundColorAnim = useRef(new Animated.Value(0)).current; useEffect(() => { // 用parallel让两个动画同时执行 Animated.parallel([ // 处理transform和opacity,保留原生驱动 Animated.timing(transformOpacityAnim, { toValue: 100, duration: 1000, useNativeDriver: true, }), // 处理backgroundColor,必须关闭原生驱动 Animated.timing(backgroundColorAnim, { toValue: 100, duration: 1000, useNativeDriver: false, }) ]).start(); }, []); // 拆分样式,把原生支持和不支持的分开 const nativeStyles = { flex: 1, opacity: transformOpacityAnim.interpolate({ inputRange: [25, 50, 100], outputRange: [0, 1, 0], extrapolate: 'clamp', }), transform: [ {translateX: transformOpacityAnim}, { rotate: transformOpacityAnim.interpolate({ inputRange: [0, 100], outputRange: ['0deg', '360deg'], }), }, ], }; const bgStyles = { backgroundColor: backgroundColorAnim.interpolate({ inputRange: [0, 100], outputRange: ['orange', 'blue'], }), }; return ( <Animated.View style={[nativeStyles, bgStyles]}> <Animated.Text style={{color:'tomato'}}>Credex</Animated.Text> </Animated.View> ); }
额外说明:
原生驱动动画是在UI线程跑的,不会阻塞JS线程,所以性能更好,但它能处理的属性是有限的;而JS驱动动画在JS线程执行,虽然性能稍弱,但能处理所有样式属性——对于背景色这种简单动画,完全不用担心性能问题。
内容的提问来源于stack exchange,提问作者Janvier




