繁体   English   中英

禁用特定项目的 RecyclerView itemAnimator

[英]Disable RecyclerView itemAnimator for specific items

在 recyclerView itemAnimator android 中,可以实时禁用/启用特定适配器位置的自动 itemAnimation 动画吗?

尝试以下代码片段:

val ignoreList = listOf<Int>(5, 6, 7)
recyclerView.itemAnimator = object : DefaultItemAnimator(){

    override fun canReuseUpdatedViewHolder(viewHolder: RecyclerView.ViewHolder): Boolean {
        if(ignoreList.contains(viewHolder.adapterPosition))
            return true;
        else
            return super.canReuseUpdatedViewHolder(viewHolder)
    }
}

您应该根据需要修改ignoreList

我也找不到简单的方法来做到这一点。 似乎动画师是布局管理器的一部分,并且对它正在制作动画的项目一无所知。 所以我唯一能想到的就是当我不想要一个只会刷新整个 RecyclerView 的动画时调用notifyDataSetChanged

我通过扩展ListUpdateCallback并覆盖onMoved方法来做到这一点。 在示例代码中更容易看到:

// my recyclerview is a list of events. You can click a checkbox to favourite an 
// event. When favourited, it moves to the top of the recyclerview. I want this move 
// animated but not vice versa. So when something is unfavourited, I don't want an 
// animation of the move when it goes back to its original position.
inner class CustomCallback(val newItems: List<Event>) : ListUpdateCallback {

    override fun onInserted(position: Int, count: Int) {
        notifyItemRangeInserted(position, count)
        Timber.d("NotificationCallback onInserted position: $position count: $count")
    }

    override fun onChanged(position: Int, count: Int, payload: Any?) {
        notifyItemRangeChanged(position, count)
        Timber.d("NotificationCallback onChanged position: $position (${newItems[position].eventName}) count: $count")
    }

    override fun onMoved(fromPosition: Int, toPosition: Int) {
        if (newItems[toPosition].isFavourite == true) {
            Timber.d("item starred so animation")
            notifyItemMoved(fromPosition, toPosition)
        } else if (newItems[toPosition].isFavourite == false) {
            Timber.d("item unstarred so no animation")
            notifyDataSetChanged()
        }
        Timber.d("NotificationCallback onMoved from: $fromPosition (${newItems[fromPosition].eventName}) to: $toPosition (${newItems[toPosition].eventName})")
    }

    override fun onRemoved(position: Int, count: Int) {
        notifyItemRangeRemoved(position, count)
        Timber.d("NotificationCallback onRemoved position: $position count: $count")
    }
}

您可以在 setItems 或 submitList 或适配器的任何方法中调用自定义 ListUpdateCallback。

// this.items is the member variable list of the items of the RV
fun setItems(newItems: List<Event>) {
    val result = DiffUtil.calculateDiff(DiffUtilCallback(this.items, newItems))
    result.dispatchUpdatesTo(CustomCallback(newItems))
    this.items.clear()
    this.items.addAll(newItems)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM