Repeat AnimatorSet

2020-06-08 06:58发布

Is there a simple way to repeat a Android AnimatorSet (infinite)? Can I set a AnimationListener and restart the AnimatorSet by calling start() again?

My AnimatorSet contains two animations that are played sequentially. So if I set the repeat mode of both single animation to repeat, than the first will be repeated while the second runs, right?

7条回答
Bombasti
2楼-- · 2020-06-08 07:08

How about this?

@Override
public void onAnimationEnd(Animator animation) {
    if (!mCanceled) {
        animation.reset();  //<- added.
        animation.start();
    }
}
查看更多
ゆ 、 Hurt°
3楼-- · 2020-06-08 07:10

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.

查看更多
叛逆
4楼-- · 2020-06-08 07:11

There is an answer for the first two questions

Is there a simple way to repeat a Android AnimatorSet (infinite)? Can I set a AnimationListener and restart the animatorSet by calling start() again?

Yes, there is:

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();

The answer for the third question, is no. The first animation will be repeated and after all repetitions the succeeding animation will be started.

查看更多
Rolldiameter
5楼-- · 2020-06-08 07:12

Set Infinite repeat count and restart / reverse repeat mode to all child animations

animatorSet.childAnimations.forEach {
            val animator  = it as ObjectAnimator
            animator.repeatCount = ObjectAnimator.INFINITE
            animator.repeatMode = ObjectAnimator.RESTART / REVERSE
}
查看更多
ゆ 、 Hurt°
6楼-- · 2020-06-08 07:20

So, none of the above options are appropriate.

If you use:

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

you will end up getting stackOverFlow exception sometimes.

The best thing is to do something like:

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();
查看更多
我想做一个坏孩纸
7楼-- · 2020-06-08 07:24

No, you can't repeat AnimatorSet, you can only repeat of a single ObjectAnimator/ ValueAnimator

But you can use PropertyValuesHolder, so that you can make an ObjectAnimator from a set of PropertyValuesHolder

here's example

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()
}
查看更多
登录 后发表回答