使用 Kotlin 在 Android 上从 ViewModel 中的 LiveData 更新 ListView 中的元素

Update element in ListView from LiveData in ViewModel on Android using Kotlin

我正在制作一个由单个 activity.

组成的应用程序

用户可以通过单击按钮创建一个预定义大小的数组。使用另一个按钮,我希望使用各种算法对数组进行排序。

算法及其执行时间显示在ListView中。请参见下面的屏幕截图作为示例:

我的listViewMainActivity中是这样创建的:

listView.adapter = MyCustomAdapter(this)

下面是适配器代码:

class MyCustomAdapter(context: Context): BaseAdapter() {

    private val mContext: Context = context

    val names = MainActivityViewModel().allAlgorithms

    override fun getCount(): Int {
        return names.size
    }

    override fun getItem(p0: Int): Any {
        return names[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {

        val layoutInflater = LayoutInflater.from(mContext)
        val row = layoutInflater.inflate(R.layout.row_algorithm, p2, false)

        val nameTextView = row.findViewById<TextView>(R.id.algoName)
        nameTextView.text = names[p0].name

        val timer = row.findViewById<TextView>(R.id.timer)
        timer.text = names[p0].time

        return row
    }
}
来自我的 ViewModel

allAlgorithmsMutableList<Algorithm>.

算法class:

class Algorithm(var name: String, var time: String = "0.00 sec")

目前这个 MutableList<Algorithm> 是使用 listOf(various algo names) 初始化的。这意味着时间保持默认值。

现在当用户点击开始基准测试按钮时,这个函数在我的 ViewModel:

中被调用
private var _executionTime = MutableLiveData<Long>(timer)
val executionTime: LiveData<Long>
    get() = _executionTime

private var _index = MutableLiveData(0)
val index: LiveData<Int>
    get() = _index

fun startBench() {
    for ((i,v) in names.withIndex()) {
        _executionTime.value = measureTimeMillis {
            arr.sort() // is the arr generated by clicking the button
        }
        _index.value = i
    }
}

我稍后会为每个算法制作不同的函数,但现在我希望我的 ListView 更新为我的 executionTime.value() 以获得正确的算法。

我试图在我的适配器中放置一个观察器,但我无法获得 ViewModelProvider,因为我没有找到访问 LifeCycleOwner 的方法。

我也曾尝试更新我的 allAlgorithm 列表,但当然它不会更新 UI。

我的问题:

我以前遇到过类似的情况。我认为虽然适配器生命周期与 activity 生命周期紧密相关,因此我可以将 LifecycleOwner 传递给适配器并且它完美运行

我什至在我的列表中插入了 500 多个项目来测试性能,每个列表项目都持有一个 LiveData 观察者,我没有发现任何问题。

也许这不是最好的解决方案,但至少你可以试一试

我犯了一个非常明显的错误,导致我的 notifyDataSetChanged() 无法工作:

MyCustomAdapter 中,我没有传递 MainActivityViewModel 的原始版本,而是实例化了新的 viewModel 每个不智能的调用。

简单的解决方法是像这样将我的 MainActivityViewModel 实例传递给适配器:

    val adapter = MyCustomAdapter(this, viewModel)
    listView.adapter = adapter

并相应地修改适配器:

class MyCustomAdapter(context: Context, vm: MainActivityViewModel): BaseAdapter()

并考虑了更改。