You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DiffUtils更新条目时areContentsTheSame恒返回true,Adapter不更新问题

RecyclerView Adapter 提交更新后未刷新条目问题解决

问题场景

UI层执行以下代码尝试更新列表条目:

val toMutableList = mAdapter.currentList.toMutableList()
// 更新第5个位置的数据
val deviceItem = toMutableList[5]
deviceItem.deviceEntity.onLineRefresh = false
mAdapter.submitList(toMutableList)

对应的DiffUtil.ItemCallback实现如下:

override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
    TLog.d("DeviceListAdapter", "areItemsTheSame: ")
    return oldItem.deviceId == newItem.deviceId
}

override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
    return oldItem == newItem
}

执行后发现Adapter并未更新目标条目,且areContentsTheSame方法始终返回true。

问题原因

currentList.toMutableList()只是做了浅拷贝——新列表里的DataItem对象和原列表的对象引用完全一致。修改deviceItem.deviceEntity.onLineRefresh时,原列表中的对应对象也被同步修改了。当submitList触发DiffUtil对比时,新旧条目本质是同一个对象,oldItem == newItem自然返回true,DiffUtil判定内容无变化,因此不会触发条目刷新。

解决方案

必须对列表中的每个DataItem进行深拷贝,让新列表里的对象都是全新实例,修改新对象的属性不会影响原列表的对象。

示例实现(需根据你的DataItem结构调整深拷贝逻辑):

// 给DataItem添加深拷贝方法(如果是data class,可借助copy方法实现)
data class DataItem(
    val deviceId: String,
    val deviceEntity: DeviceEntity
) {
    fun deepCopy(): DataItem {
        // 若DeviceEntity还有嵌套对象,需递归拷贝所有属性
        return copy(
            deviceEntity = deviceEntity.copy(onLineRefresh = deviceEntity.onLineRefresh)
        )
    }
}

// UI层更新代码修改为:
val newList = mAdapter.currentList.map { it.deepCopy() }.toMutableList()
val deviceItem = newList[5]
deviceItem.deviceEntity.onLineRefresh = false
mAdapter.submitList(newList)

处理后,新列表的DataItem都是独立实例,DiffUtil对比时会检测到属性变化,areContentsTheSame返回false,进而触发目标条目刷新。

内容的提问来源于stack exchange,提问作者zeng li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:30:50