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
相关产品推荐
相关产品推荐

