在没有唯一标识符的项目上使用“ListAdapter”areItemsTheSame

Posted

技术标签:

【中文标题】在没有唯一标识符的项目上使用“ListAdapter”areItemsTheSame【英文标题】:Using "ListAdapter" areItemsTheSame on items without unique identifier 【发布时间】:2021-11-19 11:12:28 【问题描述】:

要正确实现在 ListAdapter 的构造函数中传递的 DiffUtil.ItemCallback<T>,必须同时实现 areItemsTheSameareContentsTheSame

现在对于areItemsTheSame,建议使用 .因此,对于我的情况,没有可演绎的唯一标识符的数据类在哪里,我应该如何正确实现它?在这两个函数中简单地执行oldItem == newItem 时,我显然会在项目上看到一个闪烁的动画,因为它认为这是一个完全不同的项目,因为areItemsTheSame 返回了false。

那么人们如何正确解决这个问题?如果数据类型相同,那么无论如何都会返回true,这会触发areContentsTheSame 修复?如果不是,为什么?如果我现在这样做,回收器会正确理解只有一些数据发生了变化,并且只有视图的必要部分会“闪烁”新数据。

【问题讨论】:

如果您没有唯一标识符,您如何知道项目何时不同?发布您的数据类。使您确定对象相同(或不同)的最小数据更改是多少?当然,您一定已经想过实现一些东西,如果需要,您甚至可以添加一个。 areItemsTheSame 旨在快速查找是否仅位置的内容发生了更改(优化),或者项目现在是否已移动,在这种情况下需要完全重新绑定 viewHolder。所以你需要有一种方法来唯一地标识一行,无论这是 1 字段还是“n”是你的 2。 【参考方案1】:

那么人们如何正确地解决这个问题呢?

“解决方案”是为每一行设置一个唯一标识符(这对于大多数关系数据结构来说是一个很好的建议)。

您可以在任一方法中组合字段,回调为您提供两个项目(旧的和新的),您可以决定在其中做什么/比较。

当项目“相同”(由您的实现确定)时,这允许 RecyclerView/Adapter 组合做出假设(和优化)。

当项目被确定已更改(意味着它们现在是两个不同的项目)时,必须发生一组不同的事情(动画、重新绑定、确定 viewType 等)。 UI 的更多工作。

所以不要与框架对抗,而是提供一个唯一标识符,即使它由多个字段组成。我很想看看您的数据类,以了解为什么没有唯一的方法来识别单行。

【讨论】:

模型来自here,它是从 GraphQL 生成的模型here 构造的。那里没有明确的唯一性。但由于它是 ConcatAdapter 的一部分,它始终是一种 Header 类型。所以也许我可以让它永远真实,让它知道它不必闪烁? 所以你是说两个不同的OfferModel 可以有相同的titlestartDate?你不能要求后端提供一个唯一的标识符(我确定他们有一个,GraphQL 与否,这最终会在某个地方的表中)。 尤其是是 GraphQL,您可以在其中随意调整查询。 “所以也许我可以让它永远真实,让它知道它不必闪烁”这会起作用,但你愚弄系统,也许玩火。但是,如果您在未来没有看到任何重大问题,那么请务必使用。 是的,马丁,这可能是最好的方法。总体来说很好学,不要玩系统,尽量遵守规则。在这种情况下,我说这是一个选项,因为据我所知,该适配器中只显示了其中的 1 个。但正如我所说,“据我所知”。如果我弄错了,这可能会导致将来出现问题。但是非常感谢您的意见,它非常有帮助!

以上是关于在没有唯一标识符的项目上使用“ListAdapter”areItemsTheSame的主要内容,如果未能解决你的问题,请参考以下文章

uwp 文件系统上 StorageFile 的唯一标识符

CMDB项目采集资产数据之唯一标识

Android终端唯一性获取

RFID转发卡没有唯一的atr

如何获取Android唯一标识

设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识 zz