首页 > 解决方案 > RecyclerView、不同的 ViewTypes 和 notifyItemMoved() 导致视觉故障

问题描述

我有一个相当简单的适配器,但是动画似乎坏了;

//uses, what is effectly an array, to find out how many views to render
override fun getItemCount(): Int = data.size

//converts the view position to a layout id
override fun getItemViewType(position: Int): Int {
    return data[position].type.editorLayout
}

//renders the view from getItemViewType()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val layout = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
    return TemplateEnum.layoutList[viewType]!!.createEditor(layout)
}

//binds a click event to a view
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    holder.itemView.setOnClickListener {
        moveDown(position)
    }
}

//updates the data to reflect the event and calls notifyItemMoved() to visually swap the data
private fun moveDown(position: Int) {
    data.moveDown(position)
    notifyItemMoved(position, position + 1)
}

当我使用这段代码并测试它(模拟器和物理)时,视图会闪烁并立即更新,没有动画。

我已经调查了这种行为,我发现onCreateViewHolder()我点击获取的视图被调用然后它onBindViewHolder()然后在回收器中的下一个视图onBindViewHolder()被调用。我相信这就是导致动画故障的原因,因为 android 对动画的内容感到困惑。

我还仅使用 1 个布局测试了此代码,这导致没有调用上述事件,这样做的副作用是单击侦听器永远不会反弹,并且单击一个视图会更改其他视图的位置。我不知道如何解决这个问题。

看到在任何一种情况下我都无法获得 notifyItemMoved() ,我想部分地想知道我应该如何设置一个适配器来支持它。但主要我感兴趣的是在使用不同视图类型的示例上维护动画。这怎么可能实现?

标签: androidkotlinandroid-recyclerview

解决方案


推荐阅读