Android开发DiffUtil详解,Android——DiffUtil

本文详细介绍了Android开发中DiffUtil的作用、相关概念、使用方法以及高级用法,包括如何计算两个List的差异,如何在RecyclerView中应用DiffUtil更新数据,以及如何实现部分绑定以提高性能。此外,还探讨了DiffUtil在数据源整体改变和部分改变时的处理策略,以及其内部原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阅读了大神写的代码,才知道每一行都不是白写的,写的有理有据,还很优雅。膜拜....

一、作用

可以计算两个 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) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值