AnimatedVectorDrawableCompat цикл анимации с помощью обратного вызова

Я пытаюсь реализовать анимацию в своем приложении для Android, используя AnimatedVectorDrawableCompat, для совместимости для API >= 21.

Я хочу, чтобы анимация зациклилась на время действия. Я могу воспроизводить анимацию, и она также прекрасно зацикливается на API >= 25. Но когда я запускаю ее на устройствах или эмуляторах с API с 21 по 24, я вижу анимацию только один раз. Если я устанавливаю точку останова внутри метода обратного вызова, я вижу, что он также выполняет обратный вызов, но анимация не повторяется.

Я считаю, что анимация выполняется в другом потоке, так как она не блокирует пользовательский интерфейс.

Это метод:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imageView = findViewById(R.id.image_view1);
    final AnimatedVectorDrawableCompat anim = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_pass_inside);

    imageView.setImageDrawable(anim);

    anim.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
        @Override
        public void onAnimationEnd(Drawable drawable) {

            anim.start();
        }
    });
    anim.start();
}

Из того, что я прочитал, использование библиотеки Compat должно сделать эту работу для всех уровней API от 14 и выше, но мне даже не нужно идти туда, поскольку у остальной части моего приложения есть требования, которые ставят его как минимум на 21.

Есть ли какой-нибудь (желательно не хакерский:)) способ заставить эту работу согласованно работать на всех уровнях API? Это ошибка? Я что-то пропустил?

1 ответ

Решение

Насколько я вижу, это тонкая разница между системной и компатной версиями. Кажется, что Compat вызывает обратный вызов до того, как анимация была помечена как завершенная. Так что призыв к start() игнорируется, потому что думает, что это еще не конец.

Решение обычного взлома: опубликовать Runnable чтобы запустить его, когда анимация закончилась.

new Animatable2Compat.AnimationCallback() {
  @NonNull
  private final Handler fHandler = new Handler(Looper.getMainLooper());

  @Override
  public void onAnimationEnd(@NonNull Drawable drawable) {
    Animatable2Compat avd = (Animatable2Compat) drawable;
    fHandler.post(avd::start);
  }
};
Другие вопросы по тегам