回收者视图中的DiffUtils与稳定ID

时间:2019-01-08 09:51:22

标签: android optimization android-recyclerview

我已经阅读了很多有关RecyclerView的优化的信息  已有相当一段时间,并且已经学到了很多新概念。尚未清除的一件事是,我们可以在RecyclerView中同时使用稳定ID和DiffUtils。这种方法是否可能带来好处/缺点?根据我的阅读,我认为单独使用DiffUtils会带来重用viewHolders和漂亮的动画的所有可能的好处(如果我错了,请纠正我)。详细的比较将非常有帮助。

3 个答案:

答案 0 :(得分:4)

长话短说,DiffUtill完全替代了stableIds方法。

从每个人从ListView迁移到RecyclerView的时代开始,

StableIds是一种旧方法。与ItemAnimator一起,它提供了一种简便的方法,可以直接使用简单的预测动画。预测性含义,当您仅调用notifyDataSetChanges时,RV可以推断出自己添加/删除或移动了哪些项目。

一旦DiffUtil出现,就不需要RV来推断,因为DiffUtills会告诉RV确切的信息是要移动/添加/删除哪些项目。

我在非常恶劣的条件下使用RV,其中包含数十种项目类型,并且每秒进行多次数据更新,并且花了数十个小时调试RV和动画内部,并且在其报废/取消报废/-尝试在DiffUtil顶部添加stableIds时出现2-3-steps-layout行为。

关于DiffUtill之前的2015年动画的工作原理,这很重要:

https://www.birbit.com/recyclerview-animations-part-1-how-animations-work/

https://www.birbit.com/recyclerview-animations-part-2-behind-the-scenes/

如果您对RV的内部结构感兴趣,还需要更多一点:

https://android.jlelse.eu/anatomy-of-recyclerview-part-1-a-search-for-a-viewholder-404ba3453714

答案 1 :(得分:0)

根据文档DiffUtils

  

DiffUtil是一个实用程序类,可以计算之间的差异   两个列表,并输出将   第一个列表进入第二个列表。

     

它可用于计算RecyclerView适配器的更新。看到   ListAdapter和AsyncListDiffer可以使用DiffUtil计算差异   在后台线程上。

     

DiffUtil使用Eugene W.Myers的差分算法来计算   将一个列表转换为另一个列表的最少更新次数。迈尔斯的   算法不处理已移动的项目,因此DiffUtil运行   第二次传递结果以检测已移动的项目。

并按照此答案StableIds is

稳定的ID允许ListView针对notifyDataSetChanged调用之间的项目保持相同的情况进行优化。它引用的ID是从getItemId返回的ID。

没有它,ListView必须重新创建所有View,因为它不知道两次数据更改之间项目ID是否相同(例如,ID是否只是数据中的索引) ,它必须重新创建所有内容)。有了它,它就可以避免重新创建保留其商品ID的View

希望您的想法现在会清除。

答案 2 :(得分:0)

是的,可以。

如果使用androidx.recyclerview.widget.ListAdapter(应该使用),则实际上必须提供DiffUtil。只看构造函数。然后没有什么阻止您提供稳定的ID。

实际上,如果您不使用稳定的ID,而是提交新的事件列表(只是小小的改动),则RecyclerView中的所有项目都会“闪烁”。但是,如果您使用稳定的ID,则更改效果会很好。

还知道,它们彼此之间没有依赖关系,因此您可能会在idgetItemId()的项目中使用相同的DiffUtil(或其他)字段。