我想设置一个基本的ViewModel
并存储 ArrayList
可以更新并因此观察,将其存储为 LiveData
.
问题是 ViewModel 附加的 Fragment 在调用 .observe
时似乎无法检测到我的 ArrayList 中的更改。在上面。虽然当我调试应用程序时,我可以看到 ArrayList - 称为 s2
- 确实更新了。
这是我的 View 模型:
class MainViewModel : ViewModel() {
private val _s1 = MutableLiveData<String>()
private val _s2 = MutableLiveData<ArrayList<String>>()
val s1: LiveData<String>
get() = _s1
val s2: LiveData<ArrayList<String>>
get() = _s2
init {
_s1.value = "HELLO WORLD"
_s2.value = arrayListOf("")
}
fun populateList() {
_s2.value?.clear()
for (i in 10 downTo 1) {
_s2.value?.add("$i bottles")
}
}
}
和附加的 fragment :
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
private var message2TV: TextView? = null
// ...
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
message2TV = view?.findViewById(R.id.message_2)
viewModel.s1.observe(this, Observer {
view?.findViewById<TextView>(R.id.message)?.text = it
})
viewModel.s2.observe(this, Observer {
if (it != null && it.isNotEmpty()) {
message2TV?.text = ""
it.forEach { item -> message2TV?.append("\n$item") }
}
})
message2TV?.setOnClickListener {
viewModel.populateList()
}
}
}
当我调试时,我还发现
viewModel.s2.observe()
在单击 View (并更新 ArrayList)后,不会再次调用。只有当我改变屏幕方向时,我才能让它显示列表。请问,我在这里错过了什么?
最佳答案
LiveData
当您调用 setValue
时触发更新或 postValue
在它上面,给它一个新值的引用。它无法检测到它当前持有的对象是否在内部发生了变化,例如这个可变列表正在被修改的例子。
就像现在一样,没有setValue
在您的代码中调用:
_s2.value?.clear() // _s2.getValue()?.clear()
for (i in 10 downTo 1) {
_s2.value?.add("$i bottles") // _s2.getValue()?.add(...)
}
如果你想让它调用观察者,你可以这样做:
class MainViewModel : ViewModel() {
private val _s2 = MutableLiveData<List<String>>()
val s2: LiveData<List<String>>
get() = _s2
init {
_s2.value = listOf("")
}
fun populateList() {
_s2.value = listOf() // this is a setValue call
for (i in 10 downTo 1) {
// _s2.setValue(_s2.getValue?.plus("$i bottles")
_s2.value = _s2.value?.plus("$i bottles")
}
}
}
您也可以继续使用
ArrayList
如果需要,修改它,然后调用 setValue
再次使用相同的值,但正如您已经看到的,这更容易出错:_s2.value?.add("$i bottles")
_s2.value = _s2.value // _s2.setValue(_s2.getValue)))
关于Android Jetpack : Observing ArrayList not working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50769888/