RecyclerView
DiffUtil
最大的用处就是在RecyclerView刷新时,不再无脑mAdapter.notifyDataSetChanged()
它会自动计算新老数据集的差异,并根据差异情况,自动调用以下四个方法
adapter.notifyItemRangeInserted(position, count);
adapter.notifyItemRangeRemoved(position, count);
adapter.notifyItemMoved(fromPosition, toPosition);
adapter.notifyItemRangeChanged(position, count, payload);1. 基本用法
实现DiffUtil.Callback,然后调用DiffUtil.calculateDiff()方法,计算出新老数据集转化的最小更新集,就是DiffUtil.DiffResult对象。 然后调用DiffUtil.DiffResult.dispatchUpdatesTo(RecyclerView.Adapter adapter)方法,传入RecyclerView的Adapter,最后,更新数据集即可。
//示例步骤:
public class StudentDiffCallback extends DiffUtil.Callback {
private List<Student> oldList;
private List<Student> list;
public StudentDiffCallback(List<Student> oldList, List<Student> list) {
this.oldList = oldList;
this.list = list;
}
@Override
public int getOldListSize() {
return oldList.size();
}
@Override
public int getNewListSize() {
return list.size();
}
@Override
public boolean areItemsTheSame(int i, int i1) {
return oldList.get(i).id == list.get(i1).id;
}
@Override
public boolean areContentsTheSame(int i, int i1) {
Student oldStudent = oldList.get(i);
Student student = list.get(i1);
return oldStudent.id == student.id &&
oldStudent.age == student.age &&
oldStudent.name.equals(student.name);
}
}
//使用步骤
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new StudentDiffCallback(adapter.getDatas(), list));
diffResult.dispatchUpdatesTo(adapter);
adapter.updateList(list);2.高级用法
高级用法只涉及到两个方法, 我们需要分别实现DiffUtil.Callback.getChangePayload(int oldItemPosition, int newItemPosition), 返回的Object就是表示Item改变了哪些内容。
再配合RecyclerView.Adapter.onBindViewHolder(VH holder, int position, List payloads)方法, 完成定向刷新。
payloads 参数 是一个从(notifyItemChanged(int, Object)或notifyItemRangeChanged(int, int, Object))里得到的合并list。 如果payloads list 不为空,那么当前绑定了旧数据的ViewHolder 和Adapter, 可以使用 payload的数据进行一次 高效的部分更新。
如果payload 是空的,Adapter必须进行一次完整绑定(调用两参方法)。
注意1: 没有重写DiffUtil.Callback.getChangePayload(int oldItemPosition, int newItemPosition) 时,更新列表时,有数据更新的item会闪白光,如果不想要白光的话,重写这个方法即可。
注意2:如果数据量多比较耗时,计算新老数据集差异的逻辑可以写在子线程,然后再主线程更新,减少主线程开销。
Last updated