You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android动画无法按顺序执行求助:使用AnimationSet仍并发运行

解决Android动画并发执行而非顺序执行的问题

嗨,我完全懂你现在的困扰——明明想让动画按顺序一个个跑,结果它们全凑一块儿并发执行了,就连用了AnimationSet也没解决对吧?别慌,咱们一步步拆解问题,给你几个靠谱的解决方案。

首先得先搞明白一个关键点:AnimationSet默认是让所有动画同时启动的,它的核心作用是组合多个动画一起播放,而不是实现顺序执行。这大概率就是你之前用它没效果的原因!


方案一:给动画加监听,手动链式启动

这是最直观的方式,利用AnimationListener监听上一个动画的结束事件,在回调里启动下一个动画。适合动画数量不多的场景,逻辑清晰好控制:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    TextView targetView = view.findViewById(R.id.target_view); // 假设你要动画的是这个View

    // 加载两个动画
    Animation anim1 = AnimationUtils.loadAnimation(getContext(), R.anim.slide_in);
    Animation anim2 = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);

    // 给第一个动画设置结束监听
    anim1.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}

        @Override
        public void onAnimationEnd(Animation animation) {
            // 第一个动画跑完,立刻启动第二个
            targetView.startAnimation(anim2);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {}
    });

    // 先启动第一个动画
    targetView.startAnimation(anim1);
    return view;
}

方案二:用AnimatorSet实现顺序动画(推荐)

如果你能切换到属性动画(比旧的补间动画更灵活、适配性更好),AnimatorSet专门提供了playSequentially()方法,完美解决顺序执行的需求:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    TextView targetView = view.findViewById(R.id.target_view);

    // 创建两个属性动画示例:平移+缩放
    ObjectAnimator translateAnim = ObjectAnimator.ofFloat(targetView, "translationX", 0f, 200f);
    translateAnim.setDuration(1000); // 动画时长1秒

    ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(targetView, "scaleX", 1f, 1.5f);
    scaleAnim.setDuration(1000);

    // 组合动画并设置顺序执行
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playSequentially(translateAnim, scaleAnim);
    animatorSet.start();

    return view;
}

要是你非得用补间动画,也能把补间动画包装成Animator放进AnimatorSet里管理,同样能实现顺序效果。


补个坑:你的AnimationSet为啥没生效?

如果你还是想用AnimationSet,那一定要记得设置顺序模式——默认是ORDERING_TOGETHER(同时执行),得手动改成ORDERING_SEQUENTIAL

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    TextView targetView = view.findViewById(R.id.target_view);

    Animation anim1 = AnimationUtils.loadAnimation(getContext(), R.anim.slide_in);
    Animation anim2 = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);

    AnimationSet animSet = new AnimationSet(true);
    animSet.setOrdering(AnimationSet.ORDERING_SEQUENTIAL); // 关键!开启顺序执行
    animSet.addAnimation(anim1);
    animSet.addAnimation(anim2);

    targetView.startAnimation(animSet);
    return view;
}

之前没加这行代码的话,动画自然还是会一起跑啦。


总结一下

  1. 用补间动画的话:要么给AnimationSetsetOrdering(AnimationSet.ORDERING_SEQUENTIAL),要么用AnimationListener手动链式启动;
  2. 能用属性动画的话,优先选AnimatorSetplaySequentially(),功能更强也更适配新版本Android。

你可以根据自己的代码情况选一种试试,应该就能解决动画并发的问题啦!

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

火山引擎 最新活动