Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.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_Animation_Android Recyclerview_Kotlin - Fatal编程技术网

回收物品上的Android动画问题

回收物品上的Android动画问题,android,animation,android-recyclerview,kotlin,Android,Animation,Android Recyclerview,Kotlin,我在循环视图中的一些按钮项目上添加了点击动画 一切都很顺利,但是当我向下滚动列表时,一些按钮会以一种奇怪的状态出现,就像它们在动画阶段被冻结一样,即使这些按钮没有触发动画,而其他按钮的视图设置为不可见/消失 这是收缩动画代码的一部分,其中收缩是ValueAnimator对象 shrink.addUpdateListener { animation -> val animatedValue = animation.animatedValue as Int v.

我在循环视图中的一些按钮项目上添加了点击动画

一切都很顺利,但是当我向下滚动列表时,一些按钮会以一种奇怪的状态出现,就像它们在动画阶段被冻结一样,即使这些按钮没有触发动画,而其他按钮的视图设置为不可见/消失

这是收缩动画代码的一部分,其中收缩是ValueAnimator对象

shrink.addUpdateListener { animation ->
        val animatedValue = animation.animatedValue as Int
        v.layoutParams.width = animatedValue
        v.requestLayout()
    }
    shrink.addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationStart(animation: Animator) {
            super.onAnimationStart(animation)
            v.visibility = View.VISIBLE
            v.isEnabled = false
        }
        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            v.layoutParams.width = 0
            v.visibility = View.GONE
            v.isEnabled = false
        }
   }
我有一个
View
ViewHolder
类,在这里我可以在滚动时绑定回收视图项目的可见性

在动画生命周期中,我是否错过了与循环视图项一起工作的步骤?我在想,也许我必须处理
onAnimationStop
onAnimationPause
案例,但我不确定


任何帮助都将不胜感激。

我认为您出现问题的原因是您滚动时视图被回收。如果在视图上触发动画并滚动列表,动画将继续,但在某个点上,视图将被回收并重新填充,并导致奇怪的状态

解决方案是取消动画并将初始状态设置为适配器的
onBindViewHolder
方法中的视图。 在您的情况下,我将执行以下步骤:

  • 将值animator链接到视图保持架,这样每个视图保持架都有自己的值animator
  • 使用视图持有者的局部值animator,像现在一样触发动画
  • 你在动画中的价值
  • 在“将视图的可见性显式设置为可见”中,启用它并设置全宽

  • 首先删除默认的
    RecyclerView
    项目动画制作程序

    recyclerView.setItemAnimator(null);
    

    还可以取消适配器中的任何自定义运行动画
    onViewRecycled

    您可以使用
    setHasTransientState
    将视图标记为一种“脏”,这样当动画未完成时,RecyclerView不会重复使用它。这应该能解决你的问题。以下是修改后的代码:

    shrink.addUpdateListener { animation ->
        val animatedValue = animation.animatedValue as Int
        v.layoutParams.width = animatedValue
        v.requestLayout()
    }
    shrink.addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationStart(animation: Animator) {
            super.onAnimationStart(animation)
            v.setHasTransientState(true) // Mark view
            v.visibility = View.VISIBLE
            v.isEnabled = false
        }
        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            v.layoutParams.width = 0
            v.visibility = View.GONE
            v.isEnabled = false
            v.setHasTransientState(true) // "Return" it to the pool
        }
    
    }


    这正是PropertyImation在引擎盖下所做的。希望这会有所帮助:)

    您能提供适配器类吗?RecyclerView有自己的动画API,因此可以正确处理ViewHolder重用。看看