我的布局中有一个回收站视图,首先它将被存储在本地数据库中的数据填充,然后在几秒钟后将使用服务器进行更新。
问题在于更新时,回收站视图的项目突然更改,如何为回收站视图设置动画以平滑地更改项目?
我这样通知我的回收者视图:
fun add(list: List<BestStockModel>) {
items.clear()
items.addAll(list)
notifyItemRangeChanged(0, list.size)
}
答案 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
正确地触发计算。