mon*_*key 5 api animation android
我正在为支持 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()
}
}
Run Code Online (Sandbox Code Playgroud)
好的,我找到了解决方案。之前用过这个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>
Run Code Online (Sandbox Code Playgroud)
第一项是法线矢量可绘制,第二项是动画矢量可绘制:
<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>
Run Code Online (Sandbox Code Playgroud)
然后我将 LayerDrawable 设置为 ImageView,如下所示:
imageView.setImageResource(R.drawable.layer_list)
Run Code Online (Sandbox Code Playgroud)
这里的问题是动画矢量可绘制对象在 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)
Run Code Online (Sandbox Code Playgroud)
这里动画可绘制对象显式实例化为 AnimatedVectorDrawableCompat,因此可以使用 registerAnimationCallback 方法:
animatedDrawable.registerAnimationCallback(...)
Run Code Online (Sandbox Code Playgroud)