【问题标题】:DiffUtils vs stable Ids in recycler view回收站视图中的 DiffUtils 与稳定 ID
【发布时间】:2019-06-02 23:45:34
【问题描述】:

我已经阅读了很多关于 RecyclerView 中的优化的信息 很长一段时间,学到了很多新概念。还不清楚的一件事是,我们能否在 RecyclerView 中同时使用稳定的 id 和 DiffUtils。这种方法是否有可能的好处/缺点?根据我的阅读,我认为单独使用 DiffUtils 将提供重用 viewHolders 和漂亮动画的所有可能好处(如果我错了,请纠正我)。详细的比较会很有帮助。

【问题讨论】:

  • AFAIK 你是对的。至于稳定的 id,我们需要覆盖一个方法,即 getItemId,它在我看来就像 diff utils 的一个子集。使用稳定的 ID 可以防止视图持有者闪烁。这实际上与 DiffUtils 相同。
  • 我也有同样的疑问。但我认为这里的回复表明 hasStableIds 是一种遗产,而 diffutil 似乎是正确的前进方向。我看不到任何专业人士同时使用两者。

标签: android optimization android-recyclerview


【解决方案1】:

根据文档DiffUtils

DiffUtil 是一个实用类,可以计算两者之间的差异 两个列表并输出一个更新操作列表,该列表将 第一个列表进入第二个列表。

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

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

根据这个答案StableIds is

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

没有它,ListView 必须重新创建所有 Views,因为它无法知道数据更改之间的项目 ID 是否相同(例如,如果 ID 只是数据中的索引,它必须重新创建一切)。有了它,它可以避免重新创建保留其项目 ID 的Views。

希望你的概念现在清楚了。

【讨论】:

  • 这并不能回答问题,您是在解释这两件事是什么,但没有解释将 DiffUtils 与 stableIds 一起使用的优缺点。
【解决方案2】:

是的,你可以。

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

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

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

【讨论】:

  • 你会推荐在 Adapter 构造函数中添加 stableids 吗?
【解决方案3】:

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

StableIds 是每个人都从 ListView 迁移到 RecyclerView 时代的遗留方法。与 ItemAnimator 一起,它提供了一种简单的方法来开箱即用地获得简单的预测动画。预测意味着当您调用 notifyDataSetChanges 时,RV 可以自行推断添加/删除或移动了哪些项目,而无需担心其他回调。

一旦 DiffUtil 出现,就不需要 RV 来推断了,因为 DiffUtils 会准确地告诉 RV 哪些项目正在被移动/添加/删除。

我在非常恶劣的条件下使用 RV,有几十种项目类型,每秒更新多个数据,并且花了几十个小时调试 RV 和动画内部,没有注意到它的报废/去报废/1-有任何重大变化尝试在 DiffUtil 之上添加 stableIds 时的 2-3 步布局行为。

这是关于动画在 2015 年前后 DiffUtill 中如何工作的重要文章:

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

【讨论】: