gpt4 book ai didi

android - Recyclerview ListAdapter DiffUtil 未按预期工作

转载 作者:行者123 更新时间:2023-11-29 00:56:38 25 4
gpt4 key购买 nike

我的 diffcallback areContentsTheSame(oldItem: ItemModel, newItem: ItemModel) 总是接收相同的内容。我用状态来检查,但每次状态都是一样的。尽管状态实际上正在发生变化。我打算显示每个项目的进度。所以我定期通过状态发送当前进度。使用 diffcallback,它应该检查项目的状态是否不同,然后只更新该项目。但是它接收到的 newItem 和 oldItem 似乎是一样的。

我有一个自定义模型 ItemModel

data class ItemModel(val id: String, var title: String) {

var clickListener: ClickListener? = null
var status: Status? = null

interface ClickListener{
fun onItemClick(view: View, item: ItemModel)
fun onClick(view: View, item: ItemModel)
}

companion object {
val STATUS_CHANGED = 1

val diffCallback = object : DiffUtil.ItemCallback<ItemModel>() {
override fun areItemsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean {
// Log.i("DiffUtil", "SameItem? old status: ${oldItem.status}, new Status: ${newItem.status}")
return oldItem.id == newItem.id
}

override fun areContentsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean {
// Log.i("DiffUtil", "Checking status: new: ${newItem.status}, old ${oldItem.status}")
return oldItem.status == newItem.status
}

override fun getChangePayload(oldItem: ItemModel, newItem: ItemModel): Any? {
Log.i("DiffUtil", "Payload change: ${newItem.status?.state}")
if (oldItem.status != newItem.status) {
return STATUS_CHANGED
}
return null
}

}
}
}

和状态数据类

data class Status(val max: Int, val progress: Int, val state: State = State.NONE)

这是我的 ViewModel 类;我使用 Observable.intervalRange 生成不同的数字并更改单个列表项的状态。但是似乎 diffcallback 没有正常工作。

class FunViewModel : ViewModel() {

private val itemModels: MutableLiveData<List<ItemModel>> = MutableLiveData()

fun items(): LiveData<List<ItemModel>> {
return itemModels
}

private val compositeDisposable = CompositeDisposable()

fun initialize(itemList: List<ItemModel>) {
itemModels.value = itemList
}

private fun updateItem(item: ItemModel, status: Status) {
val currentItems = mutableListOf<ItemModel>()
if (itemModels.value == null) return
currentItems.addAll(itemModels.value!!)

Log.i("UpdateItem", "Current item: ${item.id}")

if (currentItems.isNotEmpty()) {
for ((index, el) in currentItems.withIndex()) {
// Log.i("UpdateItem", "searching: ${el.id}")
if (el.id == item.id) {
val currentItem = currentItems.removeAt(index)
Log.i("UpdateItem", "old status: ${currentItem.status}")
currentItem.status = status
currentItems.add(index, currentItem)
break
}
}
itemModels.value = currentItems
Log.i("UpdateItem", "new status: ${items().value?.get(0)?.status}")
}
}

fun startProgress(item: ItemModel) {
val disposable = getProgress(item.id).map { progress ->
val status = Status(progress.second.toInt(), progress.third.toInt(), State.IN_PROGRESS)
status
}.subscribeOn(Schedulers.single())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ status ->
updateItem(item, status)
// Log.i("FunViewModel:", "Status: progress: ${status.progress}, State: ${status.state}")
},
{ throwable: Throwable? -> Log.e("FunViewModel", "Unable to process progress!", throwable) },
{
val status = Status(20, 20, State.COMPLETED)
updateItem(item, status)
Log.i("FunViewModel:", "Status: progress: ${status.progress}, State: ${status.state}")
})
compositeDisposable.add(disposable)
}


private fun getProgress(id: String): Observable<Triple<String, Long, Long>> {
return Observable.intervalRange(0, 20, 300, 500, TimeUnit.MILLISECONDS)
.map { num -> Triple<String, Long, Long>(id, 20, num) }
}

override fun onCleared() {
super.onCleared()
if (!compositeDisposable.isDisposed) compositeDisposable.dispose()
}
}

最佳答案

好吧,我发现问题是我复制原始内容的方式不是实际复制内容,而是引用。所以我通过将项目内容复制到新的 itemModel 实例中来解决问题。完成后,diff util 就能够正确区分。

代替这个,

private fun updateItem(item: ItemModel, status: Status) {
......................................................


for ((index, el) in currentItems.withIndex()) {
if (el.id == item.id) {
val currentItem = currentItems.removeAt(index)

currentItem.status = status
currentItems.add(index, currentItem)
break
}
}
itemModels.value = currentItems
......................................
}

我这样做了,

private fun updateItem(item: ItemModel, status: Status) {
...............
if (el.id == item.id) {
currentItems.removeAt(index)
val currentItem = ItemModel(item.id, "${item.title}, ${status.progress}")
currentItem.status = status
currentItems.add(index, currentItem)
break
}
...........
}

关于android - Recyclerview ListAdapter DiffUtil 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54217587/

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