ValueAnimator实现View背景色过渡在模拟器正常、OPPO Android9真机无平滑动画
问题根因
从你提供的日志可以明确核心问题:OPPO A31(Android 9)上运行的ValueAnimator没有生成正常的渐变中间色值,只会在起始色Color.YELLOW(对应int值-256)和终止色Color.WHITE(对应int值-1)之间跳转,同时你代码存在重复触发动画的问题,导致颜色值互相覆盖。
解决方案
按优先级依次测试以下方案即可解决:
- 排查系统动画设置
先打开手机开发者选项,检查「动画时长缩放」「过渡动画缩放」「Animator时长缩放」三个选项是否被设置为0(部分厂商省电模式会默认关闭动画),调整为1x后再测试效果。 - 修复重复启动动画问题
从模拟器日志也能看到同一时间点输出多个颜色值,说明你的代码存在多次调用anim.start()的情况,多个动画同时修改背景色会互相覆盖。建议把动画对象改为类成员变量,启动前先终止已有动画:// 类成员变量 private ValueAnimator mColorAnim; // 触发动画的地方 if (mColorAnim != null && mColorAnim.isRunning()) { mColorAnim.cancel(); } mColorAnim = new ValueAnimator(); // 后面接你原有的动画配置代码 - 规避ColorOS渲染兼容问题
OPPO ColorOS 6(对应Android 9)对硬件加速下的高频背景色修改有合并渲染策略,会跳过中间帧。你可以选择其中一种方式修复:- 给目标View关闭硬件加速
background.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - 直接修改背景Drawable的颜色,避免频繁创建新的ColorDrawable
// 初始化时先设置背景Drawable ColorDrawable bgDrawable = new ColorDrawable(Color.YELLOW); background.setBackground(bgDrawable); // 动画更新回调修改Drawable颜色 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int color = (Integer)valueAnimator.getAnimatedValue(); bgDrawable.setColor(color); background.invalidate(); } });
- 给目标View关闭硬件加速
- 换用兼容性更好的API实现
直接使用官方封装的ViewPropertyAnimator实现背景色过渡,不需要手动处理Animator的生命周期,系统兼容更强:background.animate() .setDuration(3000) .setEvaluator(new ArgbEvaluator()) .backgroundColor(Color.WHITE) .start();
内容的提问来源于stack exchange,提问作者Dep1111
相关产品推荐
相关产品推荐

