【发布时间】:2020-09-20 23:59:22
【问题描述】:
我有一个Fragment A,它显示了一个项目列表。单击一个项目时,我们会导航到Fragment B,它会显示有关所选项目的更详细视图。所以,我需要在Fragment A 和B 之间进行某种交流。
在文档中(请参阅 here ),他们声明共享的 ViewModel 用于片段之间的通信是推荐的方式。所以,像这样实现它:
class SharedViewModel : ViewModel() {
// used to share Item between list and detail view
private val _selectedItem = MutableLiveData<Item>()
// Fragment B listens for this LiveData variable
val selectedItem : LiveData<Item> = _selectedItem
// called by the Fragment A which passes the selected item as argument
fun selectItem(item: Item) {
_selectedItem.value = item
}
}
在Fragment B 中,我们像这样监听selectedItem LiveData 变量:
....
// I use a global variable here cuz I want to use it in several different methods
private lateinit var selectedItem : Item
....
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// listen for the selected item
sharedViewModel.selectedItem.observe(viewLifecycleOwner, Observer { item ->
selectedItem = item
})
}
现在,在onStart()我有一些操作只有在selectedItem被初始化时才能操作:
override fun onStart() {
super.onStart()
doSomethingWithSelectedItem(selectedItem) //<--- CRASH
doAnotherThingWithSelectedItem(selectedItem) // probably it would crash here, too
}
此时,我得到selectedItem lateinit var 变量未初始化的异常。所以,我假设此时onViewCreated()(即selectedItem = item)中的设置尚未生效。
所以,我的问题是:当您想要初始化一个 lateinit 变量时,哪个生命周期方法是最好的,该变量的值通过两个 Fragment 之间的 ViewModel 共享?
【问题讨论】:
-
为什么你首先要有一个 lateinit 引用?我的建议是将
doAnotherThingWithSelectedItem移动到观察者并删除变量item -
你在observe上做你想做的操作,而不是onStart。你甚至不需要一个全局变量,更不用说lateinit,如果你只是在观察时将数据传递给那些方法
标签: android android-fragments android-viewmodel