问题描述
我正在制作一个由单个活动组成的应用。
用户可以通过单击按钮来创建预定义大小的数组。还有另一个按钮,我希望使用各种算法对数组进行排序。
算法及其执行时间显示在ListView
中。请参见以下屏幕截图作为示例:
我的listView
是在MainActivity
中创建的:
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
}
}
来自我的allAlgorithms
的 viewmodel
是MutableList<Algorithm>
。
Algorithm类:
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()
以使用正确的算法。
我尝试将观察者放入适配器中,但是由于找不到访问LifeCycleOwner的方法,因此无法获得viewmodelProvider
。
我还尝试过更新allAlgorithm
列表,但是当然不会更新UI。
我的问题:
- 如何使用LiveData更新ListView?
- 是否有更好的方法来实现我想要的目标?
解决方法
我以前也经历过类似的情况。我以为适配器的生命周期与活动的生命周期紧密相关,所以我可以将LifecycleOwner
传递给适配器,并且效果很好
我什至在列表中插入了500多个Item来测试性能,每个列表项都拥有一个LiveData
观察者,但是我没有发现任何问题。
也许这不是最佳解决方案,但至少您可以尝试一下
,我犯了一个非常明显的错误,导致我的notifyDataSetChanged()无法正常工作:
在MyCustomAdapter
中,我通过每个不明智的呼叫来实例化新的MainActivityViewModel
,而不是通过viewModel
的原始版本。
简单的解决方法是将我的MainActivityViewModel
实例传递给适配器,如下所示:
val adapter = MyCustomAdapter(this,viewModel)
listView.adapter = adapter
然后相应地修改适配器:
class MyCustomAdapter(context: Context,vm: MainActivityViewModel): BaseAdapter()
并考虑了更改。