我已经阅读了很多有关RecyclerView的优化的信息 已有相当一段时间,并且已经学到了很多新概念。尚未清除的一件事是,我们可以在RecyclerView中同时使用稳定ID和DiffUtils。这种方法是否可能带来好处/缺点?根据我的阅读,我认为单独使用DiffUtils会带来重用viewHolders和漂亮的动画的所有可能的好处(如果我错了,请纠正我)。详细的比较将非常有帮助。
答案 0 :(得分:4)
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,则更改效果会很好。
还知道,它们彼此之间没有依赖关系,因此您可能会在id
和getItemId()
的项目中使用相同的DiffUtil
(或其他)字段。