val oldList = ... // 老列表
val newList = ... // 新列表
val adapter:RecyclerView.Adapter = ...
// 1.定义比对方法
val callback = object : DiffUtil.Callback() {
override fun getOldListSize(): Int = oldList.size
override fun getNewListSize(): Int = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
// 分别获取新老列表中对应位置的元素
val oldItem = oldList[oldItemPosition]
val newItem = newList[newItemPosition]
return ... // 定义什么情况下新老元素是同一个对象(通常是业务id)
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldList[oldItemPosition]
val newItem = newList[newItemPosition]
return ... // 定义什么情况下同一对象内容是否相同 (由业务逻辑决定)
}
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
val oldItem = oldList[oldItemPosition]
val newItem = newList[newItemPosition]
return ... // 具体定义同一对象内容是如何地不同 (返回值会作为payloads传入onBindViewHoder())
}
}
// 2.进行比对并输出结果
val diffResult = DiffUtil.calculateDiff(callback)
// 3. 将比对结果应用到 adapter
diffResult.dispatchUpdatesTo(adapter)
DiffUtil需要 3 个输入,一个老列表,一个新列表,一个DiffUtil.Callback,其中的Callback的实现和业务逻辑有关,它定义了如何比对列表中的数据。
判定列表中数据是否相同分为递进三个层次:
-
是否是同一个数据:对应areItemsTheSame()
-
若是同一个数据,其中具体内容是否相同:对应areContentsTheSame()(当areItemsTheSame()返回true时才会被调用)
-
若同一数据的具体内容不同,则找出不同点:对应getChangePayload()(当areContentsTheSame()返回false时才会被调用)