如何顺利更改回收站视图项目

how to change recycler view items smoothly

我的布局中有一个回收视图,首先它会被存储在本地数据库中的数据填充,然后几秒钟后它会使用服务器更新。

问题是在更新的时候,recycler view 的项目突然改变了,我怎样才能为 recycler view 设置一个平滑改变项目的动画?

我像这样通知我的回收站视图:

 fun add(list: List<BestStockModel>) {
        items.clear()
        items.addAll(list)
        notifyItemRangeChanged(0, list.size)
    }

有更好的方法,您可以使用 ListAdapter link。 使用 ListAdapter 您可以简单地提交一个新列表,适配器将计算新旧列表之间的差异,并为 new/changed/deleted 项添加需要的动画。

它可以使用您提供给它的简单回调来检测差异。 下面是一个示例,您可以将其用作参考:

class HomeMoviesAdapter : ListAdapter<Movie, MoviesViewHolder>(
    //note the following callbacks, ListAdapter uses them
    // in order to find diff between the old and new items.
    object : DiffUtil.ItemCallback<Movie>() {
        override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean =
            oldItem.title == newItem.title //this can be a unique ID for the item

        override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean =
            oldItem == newItem
    }
) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MoviesViewHolder {
        val v: View = LayoutInflater.from(parent.context)
            .inflate(R.layout.movies_item_view, parent, false)
        return MoviesViewHolder(v)
    }

    override fun onBindViewHolder(holder: MoviesViewHolder, position: Int) {
       //your binding logic goes here as usual.
    }
}

然后从您拥有列表的地方(例如:片段),您可以执行以下操作:

adapter.submit(newList)

这就是列表适配器为您制作所需动画的全部内容。

不过有一个问题:如果提交相同的列表引用,适配器会认为它与旧列表相同,这意味着它不会触发差异计算。请注意以下示例:

//the following is a bad practice DO NOT do this!
val list: MutableList<Int> = mutableListOf(1, 2, 3)

adapter.submitList(list)

list.clear()
list.add(7)
adapter.submitList(list) //nothing will happen, since it's the same ref

将其与以下内容进行比较:

//the following is good practice, try to do the following!
adapter.submitList(listOf(1, 2, 3))
adapter.submitList(listOf(7)) //will delete all the old items, insert 7 and will also trigger the need animations correctly.

虽然它们看起来很相似,但它们完全不同:第二个向适配器提交了一个全新的列表“reference-wise”,这将导致 ListAdapter 正确触发计算。