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

时间:2020-09-05 18:38:53

标签: android android-recyclerview notifydatasetchanged

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

问题在于更新时,回收站视图的项目突然更改,如何为回收站视图设置动画以平滑地更改项目?

我这样通知我的回收者视图:

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

1 个答案:

答案 0 :(得分:1)

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

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

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.

尽管它们看起来很相似,但是却有很大不同:第二个向适配器提交了一个全新的列表,“按引用的方式”,这将导致ListAdapter正确地触发计算。