Android DiffUtil
Android 的recyclerview-v7:24.2.0 发布后多了个DiffUtil工具类,这个工具类能够大大解放了Android开发者的一个苦恼:RecyclerView局部刷新和重新刷新时实际只改变了部分数据。
DiffUtil能够计算两个列表之间的差值,并计算出旧列表变换到新列表的过程(DiffResult),DiffResult可以直接应用到RecyclerView的Adapter中,DiffResult会使用Adapter的notifyItemRangeChanged等方法来更新RecyclerView。
DiffUtil使用了Eugene W.Myers's difference algorithm 去计算从旧集合到新集合的最小更新序列,Myers 算法并没有处理集合中的子项偏移情况,所以如果选择了要计算偏移情况的话,需要进行第二次的运算来检查子项偏移,所以会产生更多的计算时间成本。当集合的数据量较大时,Myers算法的处理时间会较长,所以不要在集合数据量大时在主线程进行Diff运算,应该放在后台线程中进行运算,将运算结果(DiffResult)在主线程进行更新RecyclerView。需要值得注意的是,子项偏移的运算会比较明显得增加Diff时间,所以在集合默认是排序情况下,关闭该功能。
DiffUtil的Demo可以在网络上其他地方找到,这里不再赘述,只简单提下大致使用方法。
1、calculateDiff是最核心的方法,Callback并不是我们常见的回调,更准确点说应该是一个策略
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(DiffUtil.Callback, boolean);
2、DiffUtil.Callback可实现的方法,DiffUtil会对每个position调用对应的方法,我们只需要在Callback中告诉DiffUtil,在哪个位置中,如何判别两个列表在这个位置是否是同一个子项,如果是,有没有局部变化,如果有局部变化,都变了哪里?DiffUtil只需要知道这些,就可以计算出DiffResult
/**
* A Callback class used by DiffUtil while calculating the diff between two lists.
*/
public abstract static class Callback {
/**
* Returns the size of the old list.
*
* @return The size of the old list.
*/
public abstract int getOldListSize(); /**
* Returns the size of the new list.
*
* @return The size of the new list.
*/
public abstract int getNewListSize(); /**
* Called by the DiffUtil to decide whether two object represent the same Item.
* <p>
* For example, if your items have unique ids, this method should check their id equality.
*
* @param oldItemPosition The position of the item in the old list
* @param newItemPosition The position of the item in the new list
* @return True if the two items represent the same object or false if they are different.
*/
public abstract boolean areItemsTheSame(int oldItemPosition, int newItemPosition); /**
* Called by the DiffUtil when it wants to check whether two items have the same data.
* DiffUtil uses this information to detect if the contents of an item has changed.
* <p>
* DiffUtil uses this method to check equality instead of {@link Object#equals(Object)}
* so that you can change its behavior depending on your UI.
* For example, if you are using DiffUtil with a
* {@link android.support.v7.widget.RecyclerView.Adapter RecyclerView.Adapter}, you should
* return whether the items' visual representations are the same.
* <p>
* This method is called only if {@link #areItemsTheSame(int, int)} returns
* {@code true} for these items.
*
* @param oldItemPosition The position of the item in the old list
* @param newItemPosition The position of the item in the new list which replaces the
* oldItem
* @return True if the contents of the items are the same or false if they are different.
*/
public abstract boolean areContentsTheSame(int oldItemPosition, int newItemPosition); /**
* When {@link #areItemsTheSame(int, int)} returns {@code true} for two items and
* {@link #areContentsTheSame(int, int)} returns false for them, DiffUtil
* calls this method to get a payload about the change.
* <p>
* For example, if you are using DiffUtil with {@link RecyclerView}, you can return the
* particular field that changed in the item and your
* {@link android.support.v7.widget.RecyclerView.ItemAnimator ItemAnimator} can use that
* information to run the correct animation.
* <p>
* Default implementation returns {@code null}.
*
* @param oldItemPosition The position of the item in the old list
* @param newItemPosition The position of the item in the new list
*
* @return A payload object that represents the change between the two items.
*/
@Nullable
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return null;
}
}
3、DiffResult应用到RecyclerView的Adapter.
DiffResult.dispatchUpdatesTo(RecyclerView.Adapter);
4、关于Adapter以前的一个知识点,payloads,可能有些朋友还不知道Adapter还有一个onBindViewHolder重载方法,比常见的onBindViewHolder多一个参数:List<Object> payloads。当DiffResult中有某一项出现两个列表实际上在该位置是同一个子项,但是发生了局部变化,则调用该重载方法时带上payloads,payloads中的对象可以在Callback的getChangePayload给定。payloads不会为null,所以检查payloads是否为空,为空,直接调用默认的onBindViewHolder即可。
public void onBindViewHolder(StudentViewHolder holder, int position, List<Object> payloads) {}
Android DiffUtil的更多相关文章
- Android MultiType第三方库的基本使用和案例+DiffUtil的简单用法
1.MultiType简单介绍 1.1.MultiType用于比较复杂的页面. 如下图,今日头条用到了MultiType处理各种复杂的页面. 这种还是比较简单的类型.因为一个页面也就这种类型. ...
- Android 使用 DiffUtil 处理 RecyclerView 数据更新问题
背景 RecyclerView.Adapter#notifyDataSetChanged() 会每次刷新整个布局: 每次手动调用 RecyclerView.Adapter#notifyItemXx 系 ...
- Android局部更新(RecyclerView+ DiffUtil)
一 概述 DiffUtil是support-v7:24.2.0中的新工具类,它用来比较两个数据集,寻找出旧数据集->新数据集的最小变化量. 说到数据集,相信大家知道它是和谁相关的了,就是我的最爱 ...
- Android的Kotlin秘方(II):RecyclerView 和 DiffUtil
作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...
- Android开发学习之路-DiffUtil使用教程
谷歌最近更新了Support Library 24.2.0,而DiffUtil就是在这个版本添加的一个工具类. DiffUtil是一个查找集合变化的工具类,是搭配RecyclerView一起使用的,如 ...
- Android Weekly Notes Issue #220
Android Weekly Issue #220 August 28th, 2016 Android Weekly Issue #220 ARTICLES & TUTORIALS Manag ...
- Android Weekly Notes Issue #219
Android Weekly Issue #219 August 21st, 2016 Android Weekly Issue #219 ARTICLES & TUTORIALS Andro ...
- 学 Android 是一种什么样的体验?
转眼间 2016 年的电量已不足 20%,不禁感慨 How Time Flies!不知不觉 Android 移动开发已经走过了八年的光阴,在这八年的时间中,Android 开发从最初的简单调用系统 A ...
- Android Weekly Notes Issue #253
Android Weekly Issue #253 April 16th, 2017 Android Weely Issue #253. 本期内容包括: Android O新推出的自定义字体支持; 用 ...
随机推荐
- ThreadPool for Delphi
http://sourceforge.net/projects/threadpoolpas/ http://hivelocity.dl.sourceforge.net/project/threadpo ...
- intval()和(int)转换使用与区别
<?php echo "<br/>数值强制转换:"; $string="2a"; $string1=intval($string); echo ...
- icacls备份与还原ACL列表(NTFS权限)--Robocopy
icacls c:\windows\* /save AclFile /T- 将 c:\windows 及其子目录下所有文件的 ACL 保存到 AclFile. icacls c:\windows\ / ...
- Codeforces Gym 100231G Voracious Steve 记忆化搜索
Voracious Steve 题目连接: http://codeforces.com/gym/100231/attachments Description 有两个人在玩一个游戏 有一个盆子里面有n个 ...
- Codeforces Beta Round #18 (Div. 2 Only) C. Stripe 前缀和
C. Stripe Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/18/C ...
- hdu 5273 Dylans loves sequence 逆序数简单递推
Dylans loves sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem ...
- URL路由规则实例
1.设置支持路由和写路由规则
- java list三种遍历方法性能比較
从c/c++语言转向java开发,学习java语言list遍历的三种方法,顺便測试各种遍历方法的性能,測试方法为在ArrayList中插入1千万条记录,然后遍历ArrayList,发现了一个奇怪的现象 ...
- memached+asp.net 4.0 分布式缓存
由于准备做一个商品站点,希望做一个memached缓存.折腾了一个多星期.本机是存进去取出来为空. 各种办法都试过了,还是不行.最后用同事电脑測试是能够的,然后将DEMO公布到阿里云也是能够的.支持. ...
- lucene和egg项目的异同点
1 和lucene一样 支持全域索引 2 对字符串域提供全文检索,对数字类型域提供范围查询 3 采取和lucene类似的倒排表压缩方式 4 和lucene的多级跳转表不同,egg采取的是B+树做索引, ...