Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 设置多个视图的动画会导致动画冻结_Android_Xml_Animation_Kotlin - Fatal编程技术网

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示例,更新了问题