animation duration 属性值必须是毫秒整数,xml 中 android:duration="300" 表示 0.3 秒,写 0.3 或 300ms 均无效;translate 动画的 fromxdelta/toxdelta 单位为 px、%(自身宽)或 %p(父容器宽),不可混用;过短(500ms)影响交互响应;setduration() 在动画启动后调用无效,应每次新建实例或改用 viewpropertyanimator。

animation duration 属性值单位必须是毫秒,不是秒
XML 里写 android:duration 时,数值直接代表毫秒,比如想动 0.3 秒,就得写 300,写 0.3 或 300ms 都会报错或静默失效。系统不识别小数、不解析单位后缀,只认纯整数。
常见错误现象:android:duration="0.3" 看起来像 300 毫秒,实际被当 0 处理,动画瞬间完成;android:duration="300ms" 则解析失败,整个动画可能不触发。
- 所有 XML 动画(
translate、alpha、scale)的duration都统一用毫秒整数 - 如果从 Kotlin/Java 侧动态设置,
setDuration(300)同样是毫秒,和 XML 一致,别混成秒 - 低于 16ms 的值(如
10)在 60fps 下几乎不可见,慎用
translate 动画中 fromXDelta / toXDelta 的单位是像素还是百分比?
取决于你用的是哪种 translate 动画资源 —— translate 是旧版补间动画(Animation),只支持像素(px)或百分比(%、%p),但**不能混用**,且百分比基准不同。
使用场景:做从左滑入效果,想让 View 从屏幕外左侧滑到当前位置,用 fromXDelta="-100%" 表示「自身宽度的 -100%」,而 fromXDelta="-100%p" 表示「父容器宽度的 -100%」。多数时候你要的是后者。
-
"-100%"→ 相对于 View 自身宽度(比如按钮宽 120dp,就左移 120dp) -
"-100%p"→ 相对于父容器宽度(比如屏幕宽 412dp,就左移 412dp) - 写
"-100"(无单位)→ 解析为像素,适配性差,不推荐 - 在
res/anim/slide_in.xml中定义时,务必确认父容器尺寸是否稳定,否则 %p 可能因测量顺序导致偏移异常
duration 设太短或太长会导致什么兼容性问题?
Android 对动画时长没有硬性上下限,但实际表现受系统动画缩放设置和硬件性能影响。用户开了「动画缩放:关闭动画」或设为 0.5x,所有 duration 会被乘以对应系数,300 可能变成 150 或直接跳过。
性能影响:在低端机上,duration 小于 50ms 的 translate 动画容易卡顿或跳帧;超过 500ms 则可能让用户感知延迟,尤其在手势反馈类场景(如点击按钮弹出菜单)。
- 关键交互动画(如 BottomSheet 弹出)建议控制在
250–350范围内,平衡流畅与响应感 - 避免用
duration="1000"做入场动画,用户可能误触其他控件,且 Android 12+ 的手势导航会干扰长动画的触摸判定 - 测试时务必打开「开发者选项 → 动画缩放」切到 0.5x/关闭,看动画是否仍可理解
为什么 setDuration() 在代码里调用没生效?
常见原因是动画对象已被复用或已启动。XML 加载的 Animation 是状态共享的,如果同一个 Animation 实例被多次 start(),第二次起 setDuration() 就无效 —— 因为动画内部状态已进入运行态,修改 duration 不会重置计时器。
另一个坑:用 AnimationUtils.loadAnimation() 加载后,返回的是缓存实例,多次调用拿到的是同一个对象。
- 每次需要不同 duration,应重新加载:
Animation anim = AnimationUtils.loadAnimation(ctx, R.anim.slide_in); anim.setDuration(200); view.startAnimation(anim); - 不要对正在播放的动画改
setDuration(),它不会中断当前帧或重算进度 - Android 3.0+ 推荐迁移到
ViewPropertyAnimator或ObjectAnimator,它们的setDuration()更可靠,且支持链式调用
duration,而是搞懂它在 XML 解析、系统缩放、动画复用、设备性能四层叠加下的真实行为。










