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新推出的自定义字体支持; 用 ...
随机推荐
- Java数据结构之树和二叉树(2)
从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...
- android4.4.2 短信广播变更
近期三星陆续放出android4.4.2ROM更新包,android4.4.2对短信虽说是放开了权限,但其实是加强了限制,一台手机智能通过一个设置为默认应用的短信应用软件才能发送短信,否则就无法对短信 ...
- C++ Code_Slider
主题 1. 滑块控件属性设置 2. 使用滑块控件设置颜色 3. 显示Slider的数值 4. 5. 属性 滑块控件属性设置 //代码设置属性 代码:: ////////////// ...
- 使用AmplifyJS和JQuery编写更好更优雅的javascript事件处理代码
事件(或消息)是一种经常使用的软件设计模式.可以减少消息处理者和消息公布者的之间的耦合,比方J2EE里面的JMS规范.设计模式中的观察者模式(也叫公布/订阅模式).这对于javascript代码相同适 ...
- Android 图像压缩,和LRU算法使用的推荐链接
近两日,看的关于这些方面的一些教程数十篇,最好的当属google原版的教程了.国内有不少文章是翻译这个链接的. 需要注意的一点是:Android的SDK中的LRU算法在V4包和Util包中各有一个,推 ...
- android安全:forceStopPackage对android的Alarm的影响
也许一些使用alarmmanager做定时任务的同学遇到过这样的问题:设定alarm后,进入设置-->应用程序管理-->强行停止app后,定时任务就失效了. 简单的讲就是:force st ...
- SharedObject使用:在FluorineFx.net与Flex中使用共享对象维护在线用户列表实例【转】
一.添加一个新的FluorineFx的服务类项目OnLineService,删除原有的Sample.cs,并添加一个用户类定义与一个ApplicationAdpater类:如下: /*-- User. ...
- TP复习16
'APP_GROUP_LIST' => 'Home,Admin', //项目分组设定'DEFAULT_GROUP' => 'Home', //默认分组 开分组复制上面 AjaxReturn
- 关于Android圆形图片的一种优化方案(可以显示网络图片)
在Android App中,我们经常看到圆形头像图片,然后网上也有很多开源的控件.刚好这个项目用到了,也去找了一些开源的,发现并不完美,所以只好自己优化了,废话不多说,先上效果图: 下面是源码:本人能 ...
- iOS开发——UI篇Swift篇&UISegmentedControl
UISegmentedControl override func viewDidLoad() { super.viewDidLoad() titleLabel.text = titleString / ...