Android 设置多个视图的动画会导致动画冻结
我有一个简单的动画,使视图从屏幕的一侧转到另一侧,并在动画文件夹中定义为Android 设置多个视图的动画会导致动画冻结,android,xml,animation,kotlin,Android,Xml,Animation,Kotlin,我有一个简单的动画,使视图从屏幕的一侧转到另一侧,并在动画文件夹中定义为left\u to_right.xml: 我想要的是多个视图同时在屏幕上滑动,但速度不同,因此我有另外两个xml,分别称为left_to_right_fast.xml和left_to_right_slow.xml,除了持续时间不同外,它们完全相同 因此,在我的视图类中,我有以下方法来创建条纹图像并为其设置动画,动画完成后,我将其删除并制作另一个: private fun doAStripe() {
left\u to_right.xml
:
我想要的是多个视图同时在屏幕上滑动,但速度不同,因此我有另外两个xml,分别称为left_to_right_fast.xml
和left_to_right_slow.xml
,除了持续时间不同外,它们完全相同
因此,在我的视图类中,我有以下方法来创建条纹图像并为其设置动画,动画完成后,我将其删除并制作另一个:
private fun doAStripe() {
if (!isRunning) return
val stripe = makeStripe()
stripeHolder.addView(stripe)
stripe.animation.onAnimationEnd {
(stripe.parent as ViewGroup).removeView(stripe)
doAStripe()
}
stripe.animate()
}
private fun makeStripe(): AppCompatImageView {
val imageView = AppCompatImageView(context)
imageView.layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
imageView.setImageResource(listOf(R.drawable.cp_stripe_blue, R.drawable.cp_stripe_gray, R.drawable.cp_stripe_red).random())
imageView.clearAnimation()
imageView.animation = AnimationUtils.loadAnimation(context, listOf(R.anim.left_to_right, R.anim.left_to_right_fast, R.anim.left_to_right_slow).random())
imageView.x = width / 2f
imageView.y = (0..(stripeHolder.height)).random().toFloat()
return imageView
}
因此,当我调用doAStripe()
时,它会按预期工作,一条条纹会在屏幕上滑动并重复
但我希望能够同时运行多个条纹,因此我尝试连续三次调用doAStripe()
,但当我这样做时,条纹第一次在屏幕上似乎都是动画,但当再次出现时,它们不会移动,静止几秒钟,然后消失,新的条纹取代了它们
因此,似乎动画正在发生,因为onAnimationEnd
正在被调用。。。但事实并非如此。有人知道原因吗
另外,我的onAnimationEnd
就是这个方便的扩展:
fun Animation.onAnimationEnd(callback: () -> Unit) {
setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationRepeat(p0: Animation?) {
}
override fun onAnimationEnd(p0: Animation?) {
callback()
}
override fun onAnimationStart(p0: Animation?) {
}
})
}
更新:
你会注意到,如果你只调用onCreate调用
doAStripe()
,一次效果很好,但多次调用它-对于一些条纹效果很好,然后开始冻结动画。你做了一些小改动,让这两个动画同时运行,但我遵循了你的存储库,并且我测试过,是的,它看起来很落后,问题是,如果您在处理程序中控制动画
,Android将为您处理线程,并且您的实现存在一个问题,所有这些动画都在主线程
上,这会导致延迟
所以我就这样做了:
private fun doAStripe() {
val stripe = makeStripe()
stripeHolder.addView(stripe)
stripe.postDelayed({
(stripe.parent as ViewGroup).removeView(stripe)
doAStripe()
}, stripe.animation.duration)
stripe.animate().withLayer()
}
它看起来很平滑,但速度不是很快,也许你可以用anim
文件来控制它
我还添加了withLayer()
它为随后添加到动画中的所有视图启用硬件动画
还在makeStripe()
方法中添加了imageView.invalidate()
,以使imageView
无效。欲了解更多信息,请阅读此
这是一个简单的演示它的外观:
这不是最好的选择,但是,问题本身并没有得到正确的表述,因此,如果我有更多的时间,我会深入研究它,但从现在起,“冻结”的问题就不存在了。你到底想做的是,用不同速度左右移动的动画制作三视图?正确的?但你想让它重演?还是你也想要?动画之间的停顿?@ArbazPirwani我希望三个视图同时运行,并且每个视图之间都不停顿地重复。Github上的一个示例非常好,这样我们就可以测试您的真实代码了…@Skizo ozᴉʞ不幸的是,真正的代码是在一个巨大的私人回购我的工作,我不允许公开。也许我会很快制作一个演示应用程序,并给出一个链接。@skizoozᴉʞS刚刚做了一个git回购,其中有一个bug示例,更新了问题