20

有没有一种简单的方法来重复一个Android AnimatorSet(无限)?我可以通过再次调用来设置AnimationListener并重新启动吗?AnimatorSetstart()

MyAnimatorSet包含两个按顺序播放的动画。因此,如果我将两个单个动画的重复模式设置为重复,则第一个动画将在第二个动画运行时重复,对吗?

4

8 回答 8

37

set it's child object animators' repeat mode and count;

objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
objectAnimator.setRepeatMode(ObjectAnimator.RESTART/REVERSE...);

This won't be able to be stopped, or cancelled, however, due to yet another bug.

clearly, I'm not a fan of the myriad ways in which you can animate things in Android, and have them all fail you in one way or the other. Hope this helps somebody else.

于 2014-08-11T23:02:19.653 回答
19

前两个问题都有答案

有没有一种简单的方法可以重复 Android AnimatorSet(无限)?我可以通过再次调用 start() 来设置 AnimationListener 并重新启动 animatorSet 吗?

就在这里:

mAnimationSet.addListener(new AnimatorListenerAdapter() {

  private boolean mCanceled;

  @Override
  public void onAnimationStart(Animator animation) {
    mCanceled = false;
  }

  @Override
  public void onAnimationCancel(Animator animation) {
    mCanceled = true;
  }

  @Override
  public void onAnimationEnd(Animator animation) {
    if (!mCanceled) {
      animation.start();
    }
  }

});
mAnimationSet.start();

第三个问题的答案是否定的。将重复第一个动画,并且在所有重复之后将开始后续动画。

于 2013-10-09T08:59:16.063 回答
3

为所有子动画设置无限重复计数和重新启动/反向重复模式

animatorSet.childAnimations.forEach {
            val animator  = it as ObjectAnimator
            animator.repeatCount = ObjectAnimator.INFINITE
            animator.repeatMode = ObjectAnimator.RESTART / REVERSE
}
于 2019-11-11T05:56:57.243 回答
2

不,您不能重复 AnimatorSet,您只能重复单个 ObjectAnimator/ValueAnimator

但是你可以使用 PropertyValuesHolder,这样你就可以从一组 PropertyValuesHolder 中制作一个 ObjectAnimator

这是一个例子

val translateY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -100f, 100f)
val alpha = PropertyValuesHolder.ofFloat(View.ALPHA, 0.3f, 0.7f)
val scaleX = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.8f, 1.2f)
val scaleY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.8f, 1.2f)
// and more

ObjectAnimator.ofPropertyValuesHolder(myView, translateY, alpha, scaleX, scaleY).apply {
    interpolator = AccelerateDecelerateInterpolator()
    // duration of each animation
    duration = 500L
    // repeat infinite count (you can put n times)
    repeatCount = ValueAnimator.INFINITE
    // reverse animation after finish
    repeatMode = ValueAnimator.REVERSE
    // start animation
    start()
}
于 2019-10-05T17:39:51.803 回答
0

出乎我的意料 - 动画框架是痛苦的根源,特别是如果你想支持 2.x。我通常在尝试做任何更复杂的事情时遇到问题。使用AnimationListener“玩家”来跟踪。我跟踪我播放的动画(比如int等),然后onAnimationEnd我开始另一个应该按顺序播放的动画。这样我就可以轻松地为我的序列“编写脚本”,而不必打扰破碎的框架。

于 2013-07-12T19:24:55.643 回答
0

然而,我找不到具有多个动画的有效解决方案,但对我有用的一个解决方案是在结束后重新开始动画。

PS我没有在这里处理取消部分。

animatorSet.doOnEnd {
   it.start()
}
于 2021-09-29T12:23:58.480 回答
-2

因此,上述选项都不合适。

如果您使用:

  @Override
  public void onAnimationEnd(Animator animation) {
    if (!mCanceled) {
      animation.start();
    }
  }

有时您最终会收到 stackOverFlow 异常。

最好的方法是执行以下操作:

Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true && getActivity() != null) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            set3.start();
                        }
                    });
                    SystemClock.sleep(1200);
                }
            }
        });
        t.start();
于 2015-06-24T18:14:01.470 回答
-3

这个怎么样?

@Override
public void onAnimationEnd(Animator animation) {
    if (!mCanceled) {
        animation.reset();  //<- added.
        animation.start();
    }
}
于 2013-12-13T09:20:16.937 回答