强制使用API​​ 21和22中的AnimatedVectorDrawableCompat来使用registerAnimationCallback

我正在使用支持Android API 19-26的应用程序绘制的动画矢量。 为了重新开始动画(这是一个自定义的圆形加载动画),我使用AnimatedVectorDrawable.registerAnimationCallback,在onAnimationEnd回调中重新开始动画。 这适用于API> = 23,并且由于AnimatedVectorDrawableCompat,它也适用于API 19。

但是,它不适用于API 21和22,因为AnimatedVectorDrawable类已经存在于这些API中,但是registerAnimationCallback方法仅在API 23中添加。我怎样才能强制运行API 21或22的设备使用AnimatedVectorDrawableCompat他们的AnimatedVectorDrawable类,以便我可以使用registerAnimationCallback?

以下是我为不同的API版本开始动画的方法(在Kotlin中):

private fun startAnimation() { if (Build.VERSION.SDK_INT >= 23) { ((circular_progress.drawable as LayerDrawable) .findDrawableByLayerId(R.id.loading_circle) as AnimatedVectorDrawable).apply { registerAnimationCallback(@TargetApi(23) object : Animatable2.AnimationCallback() { override fun onAnimationEnd(drawable: Drawable?) { super.onAnimationEnd(drawable) this@apply.start() } override fun onAnimationStart(drawable: Drawable?) = super.onAnimationStart(drawable) }) }.start() } else if (Build.VERSION.SDK_INT >= 21) { ((circular_progress.drawable as LayerDrawable) .findDrawableByLayerId(R.id.loading_circle) as AnimatedVectorDrawable).apply { start() // No registerAnimationCallback here =( } } else { ((circular_progress.drawable as LayerDrawable) .findDrawableByLayerId(R.id.loading_circle) as AnimatedVectorDrawableCompat).apply { registerAnimationCallback(object : Animatable2Compat.AnimationCallback() { override fun onAnimationEnd(drawable: Drawable?) { super.onAnimationEnd(drawable) this@apply.start() } override fun onAnimationStart(drawable: Drawable?) = super.onAnimationStart(drawable) }) }.start() } } 

好吧,我找到了解决方案。 以前我用这个LayerDrawable,在xml中定义为layer_list.xml:

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/normal_drawable"/> <item android:id="@+id/loading_circle" android:drawable="@drawable/animated_vector_drawable"/> </layer-list> 

第一项是一个可绘制的法线矢量,第二个是可绘制的矢量矢量:

 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:drawable="@drawable/..."> <target .../> <target .../> </animated-vector> 

然后,我将LayerDrawable设置为一个ImageView,如下所示:

 imageView.setImageResource(R.drawable.layer_list) 

这里的问题是动画矢量可绘制被内部实例化为API版本21和22中的AnimatedVectorDrawable,但它应该是AnimatedVectorDrawableCompat。

解决的办法是以编程方式实例化LayerDrawable,普通drawable和vector drawable:

 val normalDrawable = ContextCompat.getDrawable(context, R.drawable.normal_drawable) val animatedDrawable = AnimatedVectorDrawableCompat.create(context, R.drawable.animated_vector_drawable) val layeredList = LayerDrawable(arrayOf(normalDrawable, animatedDrawable)) imageView.setImageDrawable(layeredList) 

这里动画的drawable被明确地实例化为AnimatedVectorDrawableCompat,所以使用registerAnimationCallback方法是可能的:

 animatedDrawable.registerAnimationCallback(...)