DiffUtil和它的差量算法
前言
学习Myers'Diff
算法是从 DiffUtils
源代码开始的,但DiffUtil和它的差量算法
这篇却是文章是在写完 Myers‘Diff之贪婪算法 和 Myers‘Diff之线性空间细化 这两篇算法文章之后着手的。比较先需要学会算法才能理解代码实现并更好的进行使用。
DiffUtil介绍
在正式分析DiffUtil
之前,我们先来对DiffUtil
有一个大概的了解–DiffUtil
到底是什么东西。
类的路径:
androidx.recyclerview.widget.DiffUtil.java
大家在开发关于列表页面的时候可能会遇到下面的情况:
在一次操作里面可能会同时出现
remove
、add
、change
三种操作。像这种情况,我们不能调用notifyItemRemoved
、notifyItemInserted
或者notifyItemChanged
方法。为了视图立即刷新,我们只能通过调用notifyDataSetChanged
方法来实现。但notifyDataSetChanged
刷新是全部刷新没有动画效果。
那么有一种能通过对比知道两个列表的数据的差异,然后进行remove
、add
或change
么?
Google提供的DiffUtil
是一个实用程序类,它计算两个列表之间的差异,并输出将第一个列表转换为第二个列表的更新操作列表。
DiffUtil.DiffResult
DiffUtil在计算两个列表之间的差异时使用的Callback类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public abstract static class Callback {
//旧数据集的长度;
public abstract int getOldListSize();
//新数据集的长度
public abstract int getNewListSize();
//判断是否是同一个item;
public abstract boolean areItemsTheSame(int oldItemPosition, int newItemPosition);
//如果item相同,此方法用于判断是否同一个 Item 的内容也相同
public abstract boolean areContentsTheSame(int oldItemPosition, int newItemPosition);
//如果item相同,内容不同,用 payLoad 记录这个 ViewHolder 中,具体需要更新那个View
public Object getChangePayload(int oldItemPosition, int newItemPosition){
return null;
}
}
DiffUtil.DiffResult
此类包含有关DiffUtil#calculateDiff
调用的结果的信息。可以通过dispatchUpdatesTo
使用DiffResult
中的更新,也可以通过dispatchUpdatesTo
直接将结果流式传输到RecyclerView.Adapter
。
DiffUtil使用
1 | public class RecyclerItemCallback extends DiffUtil.Callback { |
DiffUtil中Myers算法代码
再次提醒一下代码阅读需要先了解 Myers‘Diff之贪婪算法 和 Myers‘Diff之线性空间细化 这两篇文章中的算法知识。
1 | public class DiffUtil { |
参考链接:
代码:diff-match-patch
diff2论文
Myers diff alogrithm:part 1
Myers diff alogrithm:part 2
文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦~!~!
想阅读作者的更多文章,可以查看我的公共号:
