You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AnimatorSet子动画单独设置播放时间失效,如何正确配置?

方案失效的核心原因

  • AnimatorSet内部持有独立的时间调度器,直接修改子动画的播放时间会被AnimatorSet的全局进度逻辑覆盖,尤其是调用animatorSetY.start()后,AnimatorSet会按照自身的编排规则重置所有子动画的进度。
  • 仅遍历了第一层子动画,如果AnimatorSetY存在嵌套的子AnimatorSet,深层子动画不会被处理。
  • 子动画在未处于STARTED/PAUSED状态时,setCurrentPlayTime()的调用不会生效,需要先完成动画初始化。
  • 若你在遍历设置子动画进度后调用了animatorSetY.start(),该方法会将整个动画集合的进度重置为0,直接覆盖你之前对子动画的进度修改。

可行实现方案

首先递归遍历所有层级的子动画,同时跳过AnimatorSet的全局调度,直接控制所有子动画的进度:

// 先获取AnimatorSetX的当前进度
long xCurrentPlayTime = animatorSetX.getCurrentPlayTime();
long xTotalDuration = animatorSetX.getDuration();

// 递归获取所有子动画(处理嵌套情况)
List<Animator> allChildAnimators = new ArrayList<>();
getAllChildAnimators(animatorSetY, allChildAnimators);

// 先让AnimatorSetY处于暂停状态,避免全局调度覆盖子动画进度
animatorSetY.setCurrentPlayTime(0);
animatorSetY.pause();

for (Animator anim : allChildAnimators) {
    // 这里按你的业务需求计算每个子动画对应的播放时间,示例是按X的进度比例换算
    long targetPlayTime = calculateTargetPlayTimeForChild(anim, xCurrentPlayTime, xTotalDuration);
    if (anim instanceof ValueAnimator) {
        ((ValueAnimator) anim).setCurrentPlayTime(targetPlayTime);
    }
}

// 不需要调用animatorSetY.start(),如果需要后续继续播放可以调用resume()
animatorSetY.resume();

递归获取所有层级子动画的工具方法:

private void getAllChildAnimators(Animator animator, List<Animator> result) {
    if (animator instanceof AnimatorSet) {
        List<Animator> children = ((AnimatorSet) animator).getChildAnimations();
        for (Animator child : children) {
            getAllChildAnimators(child, result);
        }
    } else {
        result.add(animator);
    }
}

排查思路

  • 打印AnimatorSetY的子动画层级,确认所有需要修改的子动画都被遍历到。
  • 调用setCurrentPlayTime前后分别打印子动画的getCurrentPlayTime()返回值,确认修改是否真的被执行,是否被后续逻辑覆盖。
  • 检查AnimatorSetY的启动逻辑,避免调用start()方法重置进度,改用resume()恢复播放。

内容的提问来源于stack exchange,提问作者ysfcyln

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:36:05