AnimatedVectorDrawableCompat 使用回调的循环动画

AnimatedVectorDrawableCompat looping animation using callback

我正在尝试使用 AnimatedVectorDrawableCompat 在我的 Android 应用程序中实现动画,以兼容 API >= 21。

我希望动画在 Activity 期间循环播放。我可以播放动画,它也会在 API >= 25 上很好地循环播放。但是当我 运行 在 API 21 到 24 的设备或模拟器上播放时,我只能看到动画一次。如果我在回调方法中设置断点,我会看到它也执行回调,但动画不会重复。

我发现动画 运行 在另一个线程上运行,因为它不会阻塞 UI。

这是方法:

@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 库应该可以让 14 岁及以上的所有 API 级别都适用,但我什至不必去那里,因为我的应用程序的其余部分都有要求最小值是 21.

是否有一些(最好是非 hacky :))方法来使这项工作在这些 API 级别上一致?这是一个错误吗?我错过了什么吗?

据我所知,这是系统版本和兼容版本之间的细微差别。 Compat 似乎在其动画被标记为已结束之前调用回调。所以对 start() 的调用被忽略了,因为它认为它还没有结束。

解决方案是通常的 hack:post 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);
  }
};