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的更多相关文章

  1. Android MultiType第三方库的基本使用和案例+DiffUtil的简单用法

    1.MultiType简单介绍 1.1.MultiType用于比较复杂的页面. 如下图,今日头条用到了MultiType处理各种复杂的页面.    这种还是比较简单的类型.因为一个页面也就这种类型. ...

  2. Android 使用 DiffUtil 处理 RecyclerView 数据更新问题

    背景 RecyclerView.Adapter#notifyDataSetChanged() 会每次刷新整个布局: 每次手动调用 RecyclerView.Adapter#notifyItemXx 系 ...

  3. Android局部更新(RecyclerView+ DiffUtil)

    一 概述 DiffUtil是support-v7:24.2.0中的新工具类,它用来比较两个数据集,寻找出旧数据集->新数据集的最小变化量. 说到数据集,相信大家知道它是和谁相关的了,就是我的最爱 ...

  4. Android的Kotlin秘方(II):RecyclerView 和 DiffUtil

    作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...

  5. Android开发学习之路-DiffUtil使用教程

    谷歌最近更新了Support Library 24.2.0,而DiffUtil就是在这个版本添加的一个工具类. DiffUtil是一个查找集合变化的工具类,是搭配RecyclerView一起使用的,如 ...

  6. Android Weekly Notes Issue #220

    Android Weekly Issue #220 August 28th, 2016 Android Weekly Issue #220 ARTICLES & TUTORIALS Manag ...

  7. Android Weekly Notes Issue #219

    Android Weekly Issue #219 August 21st, 2016 Android Weekly Issue #219 ARTICLES & TUTORIALS Andro ...

  8. 学 Android 是一种什么样的体验?

    转眼间 2016 年的电量已不足 20%,不禁感慨 How Time Flies!不知不觉 Android 移动开发已经走过了八年的光阴,在这八年的时间中,Android 开发从最初的简单调用系统 A ...

  9. Android Weekly Notes Issue #253

    Android Weekly Issue #253 April 16th, 2017 Android Weely Issue #253. 本期内容包括: Android O新推出的自定义字体支持; 用 ...

随机推荐

  1. Windows 错误代码

    Error Messages for Windows http://www.gregorybraun.com/MSWINERR.ZIP Server 4.0 Error Messages   Code ...

  2. Mac下cocos2dx-3.0打包Android时,提示&quot;SimpleAudioEngine.h&quot;not found的解决方法

    前段时间触控公布cocos2dx-3.0,在升级之后试过之后,在最初的不习惯之后,感觉比之前的好用了不少,在下之前一直是用xCode模板创建,这回算是一口气升到顶了. 之后再一次编程时须要用到Sima ...

  3. Linux文件时间属性

    Linux文件时间属性                                                                                         ...

  4. 好记心不如烂笔头之JQuery学习,第三章

    第三章中主要讲了几个对DOM进行操作的方法. 归纳如下: 属性的获取和设置: //属性的获取 $("li").attr("title"); //属性的设置 $( ...

  5. javascript 中 in操作符

    in in 操作检查对象中是否有名为 property 的属性.也可以检查对象的原型,以便知道该属性是否为原型链的一部分. 对于一般的对象属性需要用字符串指定属性的名称 var mycar = {ma ...

  6. VC编译连接选项详解(转)

    大家可能一直在用VC开发软件,但是对于这个编译器却未必很了解.原因是多方面的.大多数情况下,我们只停留在“使用”它,而不会想去“了解”它.因为它只是一个工具,我们宁可把更多的精力放在C++语言和软件设 ...

  7. 从ext2文件系统上读出超级块

    概述            本篇博客中,我们将仔细分析如何从格式化为ext2文件系统的磁盘中读取超级块并填充内存超级块结构,每次将一个格式化了ext2文件系统的磁盘(分区)挂载到挂载点的时候会调用该方 ...

  8. mysql loop if

    MYSQL: loop  if ITERATE: 跳出此次循环,直接进入到下一次循环中 LEAVE: 结束循环,跳出整个循环. demo如下: CREATE TABLE t(    v INT NOT ...

  9. php模拟多线程

    一:应该知道的: php本身是不支持多线, 但是php的好搭档,apache和linux是支持的,故lamp才是最佳组合,还在使用win服务器的现在知道为什么要用linux吧.既然是模拟的, 就不是真 ...

  10. 【源码】初探C#爬虫,持续更新中。。。

       最近看到园子里有人用python做的爬虫软件并且上传的源码,苦于不懂python,便想着用C#也实现一个简易的爬虫软件.于是昨晚花了一个多小时的时间实现了一个简单的爬虫软件,功能十分简单,但是觉 ...