使用 Kotlin 在 Android 上从 ViewModel 中的 LiveData 更新 ListView 中的元素
Update element in ListView from LiveData in ViewModel on Android using Kotlin
我正在制作一个由单个 activity.
组成的应用程序
用户可以通过单击按钮创建一个预定义大小的数组。使用另一个按钮,我希望使用各种算法对数组进行排序。
算法及其执行时间显示在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
}
}
来自我的 ViewModel
的 allAlgorithms
是 MutableList<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。
我的问题:
- 如何使用 LiveData 更新我的 ListView?
- 有没有更好的方法可以达到我想要达到的目的?
我以前遇到过类似的情况。我认为虽然适配器生命周期与 activity 生命周期紧密相关,因此我可以将 LifecycleOwner
传递给适配器并且它完美运行
我什至在我的列表中插入了 500 多个项目来测试性能,每个列表项目都持有一个 LiveData
观察者,我没有发现任何问题。
也许这不是最好的解决方案,但至少你可以试一试
我犯了一个非常明显的错误,导致我的 notifyDataSetChanged() 无法工作:
在 MyCustomAdapter
中,我没有传递 MainActivityViewModel
的原始版本,而是实例化了新的 viewModel
每个不智能的调用。
简单的解决方法是像这样将我的 MainActivityViewModel
实例传递给适配器:
val adapter = MyCustomAdapter(this, viewModel)
listView.adapter = adapter
并相应地修改适配器:
class MyCustomAdapter(context: Context, vm: MainActivityViewModel): BaseAdapter()
并考虑了更改。
我正在制作一个由单个 activity.
组成的应用程序用户可以通过单击按钮创建一个预定义大小的数组。使用另一个按钮,我希望使用各种算法对数组进行排序。
算法及其执行时间显示在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
}
}
来自我的 ViewModel
的 allAlgorithms
是 MutableList<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。
我的问题:
- 如何使用 LiveData 更新我的 ListView?
- 有没有更好的方法可以达到我想要达到的目的?
我以前遇到过类似的情况。我认为虽然适配器生命周期与 activity 生命周期紧密相关,因此我可以将 LifecycleOwner
传递给适配器并且它完美运行
我什至在我的列表中插入了 500 多个项目来测试性能,每个列表项目都持有一个 LiveData
观察者,我没有发现任何问题。
也许这不是最好的解决方案,但至少你可以试一试
我犯了一个非常明显的错误,导致我的 notifyDataSetChanged() 无法工作:
在 MyCustomAdapter
中,我没有传递 MainActivityViewModel
的原始版本,而是实例化了新的 viewModel
每个不智能的调用。
简单的解决方法是像这样将我的 MainActivityViewModel
实例传递给适配器:
val adapter = MyCustomAdapter(this, viewModel)
listView.adapter = adapter
并相应地修改适配器:
class MyCustomAdapter(context: Context, vm: MainActivityViewModel): BaseAdapter()
并考虑了更改。