阅读了大神写的代码,才知道每一行都不是白写的,写的有理有据,还很优雅。膜拜....
一、作用
可以计算两个 List 之间的差异,得到两个 List 之间的差异集,如果 List 集合很大,计算两个 List 之间的差异耗时,应该放到子线程中执行,计算得到 DiffUtil.DiffResult 后,将该结果集应用到主线程的 RecyclerView 上。
二、相关概念
1. 相关类
(1)DiffUtil.Callback
计算两个 List 之间的差异时,由 DiffUtil 调用,
(2)DiffUtil.ItemCallback
用于计算 List 中两个 non-null Item 的差异
(3)DiffUtil.DiffResult
保存了DiffUtil.calculateDiff(callback,boolean)的返回结果
2. 相关方法
(1)static DiffUtil.calculateDiff(DiffUtil.Callback cb)
(2)static DiffUtil.calculateDiff(DiffUtil.Callback cb,boolean detectMoves)
如果 old 和 new List 以相同的规则进行过排序,并且 Item 从不会移动(改变位置),那么,可以禁用 detectMoves=false,提高计算效率
三、使用
1. Item 实体类
项目中使用这个的场景可能就是:老数据已经填充好了 Adapter,这时又从网络中拉取了新数据,那么使用 DiffUtil 比较两个数据集的差异,将修改应用到 Adapter。此处为了复用旧数据源模拟新的数据集,所以为其实现Clonable接口。
public class User implements Cloneable {
private int id;
private String name;
private int age;
private String profile;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public User(int id, String name, int age, String profile) {
this.id = id;
this.name = name;
this.age = age;
this.profile = profile;
}
@NonNull
@Override
public User clone() {
User o = null;
try {
o = (User) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
2. 实现一个普通的 Adapter
继承RecyclerView.Adapter,实现相关的抽象方法
创建 ViewHolder,继承自RecyclerView.ViewHolder
在 Adapter 中保存数据源、上下文等
public class MyDiffAdapter extends RecyclerView.Adapter < MyDiffAdapter.MyTicketViewHolder > {
private List < User > mData;
private Context mContext;
private LayoutInflater mLayoutInflater;
public MyDiffAdapter(List < User > data, Context context) {
mData = data;
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
public List < User > getData() {
return mData;
}
public void setData(List < User > data) {
mData = data;
}
@NonNull
@Override
public MyTicketViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.user_item, parent, false);
return new MyTicketViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyTicketViewHolder holder, int position) {
User user = mData.get(position);
// 为控件绑定数据
}
@Override
public int getItemCount() {
return mData == null ? 0 : mData.size();
}
class MyTicketViewHolder extends RecyclerView.ViewHolder {
public MyTicketViewHolder(@NonNull View itemView) {