0

我实现ListAdapter了,那个 T 是密封类ViewHolderModel。然后,我尝试实现DiffUtil.ItemCallback要使用的Adapter,但是遇到了一个问题。

ViewHolderModel包括各种数据对象,它们是唯一的,一些对象是不明确的。

如何实现高效的 ItemCallback?

ViewHolderModel(密封类)

sealed class ViewHolderModel {
    object Error : ViewHolderModel()
    object Footer : ViewHolderModel()

    data class Header(
        val title: String,
        val description: String,
        ...
    ) : ViewHolderModel()

    sealed class Item : ViewHolderModel() {
        abstract val id: Long
        abstract val thumbnail: String

        data class Image(
            override val id: Long,
            override val thumbnail: String
            ...
        ) : Item()

        data class Video(
            override val id: Long,
            override val thumbnail: String
            ...
        ) : Item()

        data class Sound(
            override val id: Long,
            override val thumbnail: String
            ...
        ) : Item()
    }
}

项目回调

companion object {
    val Comparator by lazy {
        object : DiffUtil.ItemCallback<ViewHolderModel>() {
            override fun areItemsTheSame(oldItem: ViewHolderModel, newItem: ViewHolderModel): Boolean =
                ???
    
            override fun areContentsTheSame(
                oldItem: ViewHolderModel,
                newItem: ViewHolderModel
            ): Boolean = oldItem == newItem
        }
    }
}

我尝试将抽象字段(id)添加到ViewHolderModel如下,但看起来不太好。还有比这更好的方法吗?

sealed class ViewHolderModel {
    abstract val id : Long
    object Error : ViewHolderModel() {
        override val id: Long
            get() = Long.MIN_VALUE
    }

    object Footer : ViewHolderModel() {
        override val id: Long
            get() = Long.MIN_VALUE + 1
    }
    ...

// in ItemCallback
override fun areItemsTheSame(oldItem: ViewHolderModel, newItem: ViewHolderModel): Boolean =
                oldItem.id == newItem.id
4

1 回答 1

1

取决于您的数据的独特性。当然,如果您有一些唯一标识符会更好,但也许您的 Header 的标题已经是唯一的并且描述的内容已经可以更改?这样你就可以像下面这样使用 sth(如果你愿意,你可以深入 Item 来区分图像视频和声音)

override fun areItemsTheSame(
    oldItem: ViewHolderModel,
    newItem: ViewHolderModel
): Boolean = when {
    oldItem is ViewHolderModel.Header && newItem is ViewHolderModel.Header && oldItem.title == newItem.title -> true
    oldItem is ViewHolderModel.Item && newItem is ViewHolderModel.Item && oldItem.id == newItem.id -> true
    else -> false
}
            
于 2021-07-21T10:29:42.813 回答