【问题标题】:DiffUtil not updating ListAdapter after updating ArrayList contents更新 ArrayList 内容后,DiffUtil 不更新 ListAdapter
【发布时间】:2020-02-10 08:29:10
【问题描述】:

我正在尝试更新 MutableLiveData 中的 ArrayList。 每当我更改 ArrayList 中的内容时,ListAdapter 都不会更新。

视图模型

private var _tileNumberList:MutableLiveData<ArrayList<TileNumber>> = MutableLiveData()

var tempTileNumberList: ArrayList<TileNumber> = ArrayList()

val tileNumberList:LiveData<ArrayList<TileNumber>>
get() = _tileNumberList

init {
    for (i in 1..9){
        for (j in 1..9){
            //tileNumberList.add(TileNumber(0,i,j))
            tempTileNumberList.add(TileNumber(0,i,j))
        }
    }

 fun onStart() {

        tempTileNumberList[count].number = 8
        _tileNumberList.value = tempTileNumberList
        count++

    }

每当我调用 onStart 方法时,列表值发生变化,但 ListAdapter 没有更新为最新值

MainActivity

backTrackingViewModel.tileNumberList.observe(this, Observer {
               it?.let {
                   //adapter.submitList(null)
                   adapter.submitList( it)
               }
            Toast.makeText(
                applicationContext,
                "Hey",
                Toast.LENGTH_SHORT
            ).show()
        })

当我设置 adapter.submitList(null) 然后我的 ListAdapter 正在更新

TileNumber

data class TileNumber(var number:Int,val row:Int,val column:Int) {
}

我试过这个链接引用但没有用

ListAdapter not updating item in RecyclerView

https://stackoverflow.com/a/50062174/6925888(这不是一个好的解决方案)

DiffUtil ItemCallback areContentsTheSame() always returns true after updating an item on the ListAdapter

【问题讨论】:

  • 请添加属性tileNumberList的描述。
  • @mike 检查我也更新了问题和代码。
  • 根据链接的问题“因此,如果您将相同的列表传递给适配器,它甚至不会调用 DiffUtil”。你检查了吗?
  • 那么,你有 Toast 通知吗?
  • @sanjeev 是的,我通过了相同的列表并调用了 DiffUtil。

标签: android kotlin android-mvvm


【解决方案1】:

我认为你应该像这样初始化 tileNumberList 列表

var tileNumberList: LiveData<ArrayList<TileNumber>> =  _tileNumberList

然后像你正在做的那样在 MainActivity 中观察它

【讨论】:

  • 这没有意义
  • 为什么不呢?更改 _tileNumberList 的值将触发我们在 Fragment 中观察到的 tileNumberList
【解决方案2】:

为什么这段代码不起作用,我有两个可能的选择:

  1. 项目已就地更改 - 即您更改列表中的项目。由于列表被传递给适配器,因此适配器的列表也发生了变化。 解决方案:

    _tileNumberList.value = tempTileNumberList.toList()

  2. 您没有为 TileNumber 类覆盖 equals()hashCode()

【讨论】:

  • 谢谢,Mike,让正确的项目位置不会改变,只会改变内容。 (在列表的同一位置),我试过了,但没有运气。
  • 你也应该尝试直接设置项目:tempTileNumberList[count] = TileNumber(number = 8)
【解决方案3】:

根据ListAdapter.SubmitList() 文档,在您通过具有相同引用的列表之前,您将永远不会更新您的列表。要使其工作,您可以简单地调用:

adapter.submitList(it.toList())

【讨论】:

    【解决方案4】:

    替换这个:

     fun onStart() {
    
            tempTileNumberList[count].number = 8
            _tileNumberList.value = tempTileNumberList
            count++
    
        }
    

    用这个:

     fun onStart() {
    
            val tileNumber = tempTileNumberList[count].copy()  
            tileNumber.number = 8 
            tempTileNumberList.set(count, tileNumber)  
            _tileNumberList.value = tempTileNumberList
            count++
    
        }
    

    这里我使用的是 Kotlin 数据类 copy() 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 2011-06-12
      • 2022-01-03
      • 1970-01-01
      • 2018-10-21
      相关资源
      最近更新 更多