使用ObjectAnimator无法重启无限动画,求技术解决方案
ObjectAnimator无限动画无效果问题排查与解决
问题场景
使用ObjectAnimator实现ImageView无限旋转动画时,执行以下代码后控件始终无动画效果;但移除if-else语句后动画可正常运行。
相关代码
private var progressAnimation: ObjectAnimator? = null private fun setProgressAnimation(start: Boolean){ if (start) { progressAnimation = ObjectAnimator.ofFloat(binding.imageProgress, "rotation", 0f, 180f).apply { duration = 1600 repeatCount = Animation.INFINITE interpolator = LinearInterpolator() start() } } else progressAnimation?.cancel() }
问题原因
- 重复创建动画实例导致冲突:每次调用
setProgressAnimation(true)都会生成新的ObjectAnimator对象覆盖旧实例,旧动画可能未完全终止,会干扰新动画的执行,导致控件属性被频繁重置,视觉上看不到动画效果。 - 旋转范围设置不合理:原动画是0°到180°无限重复,实际是来回翻转而非持续旋转,可能和预期的动画效果不符,也容易出现视觉上的“卡顿”或无变化错觉。
解决方法
1. 复用动画实例,避免重复创建
先判断动画实例是否存在,不存在再初始化,确保同一时间只有一个动画作用于控件:
private var progressAnimation: ObjectAnimator? = null private fun setProgressAnimation(start: Boolean){ if (start) { // 仅在动画实例为空时初始化 if (progressAnimation == null) { // 改为0°到360°实现持续旋转 progressAnimation = ObjectAnimator.ofFloat(binding.imageProgress, "rotation", 0f, 360f).apply { duration = 1600 repeatCount = Animation.INFINITE interpolator = LinearInterpolator() } } // 动画未运行时才启动,避免重复start if (progressAnimation?.isRunning == false) { progressAnimation?.start() } } else { progressAnimation?.cancel() // 可选:取消动画后重置控件旋转角度 binding.imageProgress.rotation = 0f } }
2. 处理动画生命周期,防止内存泄漏
在页面销毁时记得清理动画资源:
override fun onDestroyView() { super.onDestroyView() progressAnimation?.cancel() progressAnimation = null }
内容的提问来源于stack exchange,提问作者Konstantin Konopko
相关产品推荐
相关产品推荐

