animation-set 的 android:duration 不生效,因为 set 仅是容器,真正起作用的是子动画各自的 android:duration;必须为每个子动画显式设置时长,或在 Java/Kotlin 中用 AnimationSet.setDuration() 批量设置。

animation-set 的 android:duration 不生效?
直接写在 set 标签上的 android:duration 是无效的。XML 动画中,set 本身不执行动画,它只是容器;真正起作用的是子动画(比如 alpha、translate)各自的 android:duration。
常见错误现象:给 set 设了 android:duration="1000",但实际动画快得像没设——因为子动画没设时长,默认是 300ms。
- 必须为每个子动画显式设置
android:duration - 如果希望所有子动画统一时长,就逐个写一遍,别偷懒只写在
set上 -
set上的android:duration在旧版 Android(如 API 10 以下)可能被忽略,新版则直接无意义
想让多个动画总时长固定,用 android:fillAfter 和 android:startOffset 控制节奏
XML 中没有“总时长”这个概念,但你可以通过协调子动画的起始偏移和持续时间,让整个 set 行为看起来符合预期时长。例如:想让一组动画共耗时 800ms,其中淡入 300ms、平移 500ms、且平移比淡入晚 200ms 开始。
关键不是靠 set 统一时长,而是靠对齐时间轴:
-
android:startOffset决定子动画相对于set开始时刻的延迟(单位 ms) -
android:duration决定该子动画自己占多少时间 -
android:fillAfter="true"让动画结束后保持最终状态,避免回弹干扰后续动画视觉连贯性
示例片段:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="300" />
<translate android:fromXDelta="0" android:toXDelta="100"
android:duration="500"
android:startOffset="200" />
</set>
Java/Kotlin 代码里调用 AnimationSet 时,setDuration() 才真正有效
XML 是声明式,而 Java/Kotlin 中的 AnimationSet 是运行时对象,它的 setDuration() 方法会**批量设置所有已添加的子动画时长**——这是 XML 没有的能力。
使用场景:动态生成动画、或需要复用同一套动画逻辑但时长随业务变化(比如网络加载慢时延长动画)。
- 调用
setDuration()必须在addAnimation()之后,否则对尚未加入的子动画无效 - 如果子动画已单独调用过
setDuration(),再对AnimationSet调用,会覆盖它们的值 - 注意兼容性:API 1+ 就支持,但低版本中某些插值器 + 时长组合可能导致帧率异常,建议最低测试到 API 16
Android 5.0+ 推荐改用 AnimatorSet + ObjectAnimator
XML 中的 set 对应老式 Animation 框架(View 动画),它只操作 View 的绘制缓存,不改变真实属性。这意味着:translationX 动画结束后,View 的 getTranslationX() 还是 0 —— 点击区域没变,布局位置也没变。
而 AnimatorSet 配合 ObjectAnimator 是属性动画,直接修改目标对象的真实字段,行为更可靠:
- XML 中对应的是
animator/目录下的animator_set.xml,不是anim/ - Java/Kotlin 中用
AnimatorInflater.loadAnimator()加载,再调用setTarget() -
AnimatorSet的setDuration()同样只影响已添加的子Animator,但推荐用ObjectAnimator.ofFloat(...).setDuration()单独控制更清晰
如果你还在 XML 里写 anim/ 下的 set,且目标是 Android 5.0+ 设备,大概率该换到属性动画体系了——不是因为 XML 写不对,而是底层机制已经过时。
容易被忽略的一点:XML 动画的 android:duration 单位永远是毫秒,没有缩写、没有默认单位,写成 "1s" 或 "100"(少个 0)都会导致行为完全不对,而且不会报错,只能靠肉眼观察或 Log 输出 duration 值来验证。










