gpt4 book ai didi

android - 具有 DiffUtil.ItemCallback 的 ListAdapter 始终认为对象相同

转载 作者:行者123 更新时间:2023-12-01 01:43:58 26 4
gpt4 key购买 nike

我正在尝试将 ListAdapter 与 Room 和 LifeData 一起使用。但是我遇到了 DiffUtil.ItemCallback 的奇怪行为 - areContentsTheSame() 方法中的对象总是相同的。
添加和删​​除对象没有问题,但更改内容有问题。

元素类别:

@Entity(tableName = "item")
data class Item(var num: Int) {

@PrimaryKey(autoGenerate = true)
var key: Int = 0

}

适配器类
class LifeAdapter : ListAdapter<Item, LifeAdapter.ViewHolder>(DiffCallback()) {

private class DiffCallback : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item) = oldItem.key == newItem.key
override fun areContentsTheSame(oldItem: Item, newItem: Item) = oldItem.num == newItem.num
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_item, parent, false)
return ViewHolder(view)
}

override fun onBindViewHolder(holder: ViewHolder, pos: Int) {
val position = holder.layoutPosition
holder.bind(getItem(position))
}

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bind(item: Item) {
itemView.findViewById<TextView>(R.id.txt_num).text = item.num.toString()
itemView.findViewById<TextView>(R.id.txt_key).text = item.key.toString()
}
}

}

Activity 类:
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val dao = getDao(this)
val data = dao.getAllItems()

val adapter = LifeAdapter()
rv.layoutManager = LinearLayoutManager(this)
rv.adapter = adapter

val nameObserver = Observer<List<Item>> { adapter.submitList(it) }

data.observe(this, nameObserver)

btn_add.setOnClickListener {
val item = Item(Random.nextInt(0, 1000))
runAsync { dao.insertItem(item) }
}

btn_change.setOnClickListener { v ->
data.value.let {
if (it!!.isNotEmpty()) {
it[0].num = 111
runAsync { dao.updateItem(it[0]) }
}
}
}

btn_delete.setOnClickListener { v ->
data.value.let {
if (it!!.isNotEmpty()) {
runAsync { dao.deleteItem(it[0]) }
}
}
}

}
}

完整项目 - https://yadi.sk/d/7tpzDhUA-udoIQ

视频 - https://youtu.be/PZYeAfGzXBg

问题出在 LifeAdapter.DiffCallback 类的方法 areContentsTheSame() 中。
如果项目内容(数量)发生变化,则在此方法中 newItem 和 oldItem 相同并且等于新项目:

enter image description here

这意味着方法 areContentsTheSame() 总是返回 true。
我通过链接(newItem === oldItem)检查了相等性,它总是错误的,因为它应该是。
我不明白出了什么问题。通过 adapter.submitList() 方法添加新列表时,newItem 和 oldItem 必须不同。

最佳答案

由于LiveData 返回相同的 List你必须创建一个新的。

这是使用 toList() 对原始答案的简短回答.

recycler.observe(this, Observer{
adapter.submitList(it.toList())
})

如果您更愿意使用 kotlin 扩展,则可以执行以下操作:
fun <T> MutableLiveData<List<T>>.add(item: T) {
val updatedItems = this.value?.toMutableList()
updatedItems?.add(item)
this.value = updatedItems
}

这样您就不必添加 toList()并且只需使用扩展名。

关于android - 具有 DiffUtil.ItemCallback 的 ListAdapter 始终认为对象相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53156597/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com