嘿,我是新来的DiffUtil in adpater。我读了一些来自堆栈溢出的文章,google文档和一些文章。我正在努力理解areItemsTheSame和areContentsTheSame的回调 of DiffUtil,但是,我不清楚这意味着什么。我正在添加一些代码,请看一下。如果我做错了,请指导我。
GroupKey
data class GroupKey(
val type: EnumType,
val sender: Sender? = null,
val close: String? = null
)EnumType
enum class EnumType {
A,
B
}发件人
data class Sender(
val company: RoleType? = null,
val id: String? = null
)RoleType
data class RoleType(
val name : String?= null
val id: String? = null
)集团
data class Group(
val key: GroupKey,
val value: MutableList<Item?>
)我将我的列表传递给适配器,它是一个Group mutableList
var messageGroupList: MutableList<Group>? = null
..
val adapter = MainAdapter()
binding.recylerview.adapter = adapter
adapter.submitList(groupList)在适配器中使用DiffUtil
MainAdapter.kt
class MainAdapter :ListAdapter<Group, RecyclerView.ViewHolder>(COMPARATOR) {
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<Group>() {
override fun areItemsTheSame(oldItem: Group, newItem: Group): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Group, newItem: Group): Boolean {
return ((oldItem.value == newItem.value) && (oldItem.key == newItem.key))
}
}
}
.....
}1.这里我需要比较键的其他属性,如类型、发件人等。也在这个DiffUtil.ItemCallback中。
2.当使用==或===时,等于()怎么办?
3.如果我们比较int、boolean或String,我们使用==E 256还是其他什么?
在这个适配器中,我调用另一个具有在适配器中传递项列表的回收视图。
项目
data class Item(
val text: String? = null,
var isRead: Boolean? = null,
val sender: Sender? = null,
val id: Int? = null
)NestedRecyclerView.kt
class NestedRecyclerView : ListAdapter<Item, IncomingMessagesViewHolder>(COMPARATOR) {
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return ((oldItem.isRead == oldItem.isRead) &&
(oldItem.sender == newItem.sender) &&
(oldItem.text == oldItem.text))
}
}
}
}同样的问题,我也需要在这里比较发送者的其他属性。
areItemsTheSame中的4.需要比较id还是oldItem == newItem?
5.如何正确地更新适配器项。在普通的循环视图中,我们使用notifiyDataSetChanged.但是在函数中,我是否需要再次调用、submitList、函数,并且它会处理所有的事情?
adapter.submitList(groupList)发布于 2021-10-21 19:10:57
问题1和4:
areItemsTheSame意味着这两个实例表示相同的数据项,即使某些内容可能不同。假设您有一个联系人列表,Jane的中间首字母已经更改,但是该行仍然应该表示相同的人员Jane。您的模型类可能有不同的实例,有一些不同的值,但它们应该表示相同的行。
因此,通常您只会比较旧的和新的项目之间的一件事,在本例中,每一项都是相同的。通常,如果您从数据库或API中获取数据,将有一些表示数据点的唯一ID,这就是您在areItemsTheSame中需要进行比较的全部内容。例如,oldItem.id == newItem.id。
areContentsTheSame意味着,如果两个实例都显示在您的列表中,它们看起来将是相同的。因此,如果您使用的是data class,那么使用oldItem == newItem就足够了,因为数据类有一个比较每个属性的equals函数。
在您的项目回调代码中,您的areItemsTheSame看起来是正确的,但是您的areContentsTheSame过于复杂。因为Item是一个数据类,所以只需要直接比较这两个项。
override fun areContentsTheSame(oldItem: Item, newItem: Item) = oldItem == newItem在您的组回调代码中,如果这是确定项目是否相同的有效方法,也许可以比较新旧项的GroupKeys。由于您只使用直接的==比较,当项目部分更改时,您可能会有一些视觉缺陷,如视图消失和重新出现,而不是简单地进行一些文本更改。
问题2你很少需要在Kotlin中使用===。它不仅检查两个项是否等效,而且还检查这两个项是否引用了内存中完全相同的实例。这完全不适合于DiffUtil.ItemCallback。
问题3 ==是比较任意两个对象的正确方法。在Kotlin中,即使是原语也应该这样进行比较,因为它们的行为就像对象一样。
问题5和ListAdapter,您应该始终使用submitList而不是notifyDataSetChanged。notifyDataSetChanged将导致对所有视图进行毫无意义的刷新,并使使用ListAdapter和DiffUtil的目的落空。
https://stackoverflow.com/questions/69666866
复制相似问题