Повторить AnimatorSet

Есть ли простой способ повторить Android AnimatorSet (бесконечный)? Могу ли я установить AnimationListener и перезапустить AnimatorSet, снова вызвав start()?

My AnimatorSet содержит две анимации, которые воспроизводятся последовательно. Итак, если я задаю повторному режиму как одной анимации, повторяющейся, чем первая будет повторяться, а вторая будет выполняться, правильно?

Ответ 1

установить режим повторения и подсчет аниматоров дочерних объектов

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

Однако этого нельзя будет остановить или отменить из-за еще одной ошибки.

ясно, что я не являюсь поклонником множества способов, которыми вы можете анимировать вещи в Android, и заставить их всех терпеть неудачу в том или ином виде. Надеюсь, это поможет кому-то другому.

Ответ 2

Есть ответ на первые два вопроса

Есть ли простой способ повторить Android AnimatorSet (бесконечный)? Могу ли я установить AnimationListener и перезапустить AnimatorSet, снова вызвав start()?

Да, есть:

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

Ответ на третий вопрос - нет. Первая анимация будет повторяться, и после всех повторений будет запущена следующая анимация.

Ответ 3

Из моей головы - анимационная среда - источник боли, особенно если вы хотите поддерживать 2.x. У меня обычно возникали проблемы с наборами, которые пытались выполнить любой более сложный вид с помощью AnimationListener вида "игрока". Я отслеживаю, на какой анимации я играю (например, int и т.д.), А затем на onAnimationEnd Я запускаю другую, которая должна быть в последовательности. Таким образом, я могу легко "script" выполнить свою последовательность и не беспокоить сломанную структуру.

Ответ 4

Нет, вы не можете повторить AnimatorSet, вы можете повторить только один ObjectAnimator/ValueAnimator

Но вы можете использовать PropertyValuesHolder, чтобы создать ObjectAnimator из набора PropertyValuesHolder

вот пример

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

Ответ 5

Итак, ни один из вышеперечисленных вариантов не подходит.

Если вы используете:

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

Ответ 6

Как насчет этого?

@Override
public void onAnimationEnd(Animator animation) {
    if (!mCanceled) {
        animation.reset();  //<- added.
        animation.start();
    }
}