Android视图动画onAnimationRepeat()未触发问题咨询
嘿,我来帮你排查这个动画重复回调没触发的问题~先看一下你代码里的几个关键错误点,再给你对应的解决方案:
问题根源分析
1. repeatMode赋值错误
你代码里写了connectingAnimationWave1.repeatMode = Animation.INFINITE,这是完全错误的!repeatMode的合法取值只有Animation.RESTART(默认,重复时从头开始)和Animation.REVERSE(重复时反向播放),而INFINITE是repeatCount的专属取值,用来设置无限重复。这个错误会直接导致动画的重复逻辑紊乱,是onAnimationRepeat()不触发的核心原因之一。
2. 动画集与子动画的重复设置冲突
你的XML动画文件里,<scale>和<alpha>两个子动画都单独设置了android:repeatCount="infinite",这意味着两个子动画会各自独立无限循环。此时外层的AnimationSet(动画集)的重复设置会被忽略,因为子动画一直在循环,动画集本身永远不会完成一次完整的循环周期,自然不会触发onAnimationRepeat()回调。
解决方案
方案一:统一控制动画集的重复逻辑(推荐)
移除子动画的重复设置,把无限重复的逻辑统一放在动画集上:
第一步:修改XML动画文件
删除两个子动画的android:repeatCount="infinite"属性:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:duration="1500" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:toXScale="7.0" android:toYScale="7.0" /> <alpha android:duration="600" android:fromAlpha="1.0" android:startOffset="900" android:toAlpha="0.0" /> </set>
第二步:修正Kotlin代码
把错误的repeatMode赋值改成合法值,同时用startAnimation()启动动画(比直接赋值animation更可控):
val connectingAnimationWave1 = AnimationUtils.loadAnimation(activity, R.anim.anim_otp_wave_1) connectingAnimationWave1.repeatCount = Animation.INFINITE // 修正repeatMode为合法值,这里用RESTART表示重复时从头播放 connectingAnimationWave1.repeatMode = Animation.RESTART connectingAnimationWave1.setAnimationListener(object : Animation.AnimationListener{ override fun onAnimationRepeat(p0: Animation?) { Log.d("MyAnimListener", "Repeat " + p0!!.startOffset) } override fun onAnimationEnd(p0: Animation?) { Log.d("MyAnimListener", "End " + p0!!.startOffset) } override fun onAnimationStart(p0: Animation?) { Log.d("MyAnimListener", "Start " + p0!!.startOffset) } }) // 使用startAnimation启动动画,确保正常触发回调 view_wave_1.startAnimation(connectingAnimationWave1)
方案二:监听子动画的重复回调(如果需要子动画独立循环)
如果你的业务逻辑要求<scale>和<alpha>各自无限重复,可以单独给每个子动画设置监听器:
val connectingAnimationWave1 = AnimationUtils.loadAnimation(activity, R.anim.anim_otp_wave_1) as AnimationSet // 获取动画集中的子动画(索引0是scale,索引1是alpha) val scaleAnim = connectingAnimationWave1.getAnimation(0) val alphaAnim = connectingAnimationWave1.getAnimation(1) // 给scale动画设置监听器 scaleAnim.setAnimationListener(object : Animation.AnimationListener{ override fun onAnimationRepeat(p0: Animation?) { Log.d("ScaleAnim", "Scale动画重复了") } override fun onAnimationEnd(p0: Animation?) { Log.d("ScaleAnim", "Scale动画结束了") } override fun onAnimationStart(p0: Animation?) { Log.d("ScaleAnim", "Scale动画启动了") } }) // 给alpha动画设置监听器 alphaAnim.setAnimationListener(object : Animation.AnimationListener{ override fun onAnimationRepeat(p0: Animation?) { Log.d("AlphaAnim", "Alpha动画重复了") } override fun onAnimationEnd(p0: Animation?) { Log.d("AlphaAnim", "Alpha动画结束了") } override fun onAnimationStart(p0: Animation?) { Log.d("AlphaAnim", "Alpha动画启动了") } }) view_wave_1.startAnimation(connectingAnimationWave1)
注意:这种情况下,动画集的onAnimationRepeat()仍然不会触发,因为子动画一直在独立循环,动画集本身没有完整的循环周期。
内容的提问来源于stack exchange,提问作者Raj Suvariya

