我有一个带有jetpack导航的单个 Activity 应用程序,我需要一个对象变量来用于许多 fragment 中的所有应用程序。因此,我使用 ViewModel,并且创建了一个提供 ViewModel 的 Parent Fragment 类:
class MyViewModel : ViewModel() {
var myData : CustomClass? = null
...
}
open class ParentFragment : Fragment {
val model : MyViewModel by activityViewModels()
lateinit var myData : CustomClass
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.myData?.let {
myData = it
}
}
}
myData
在我使用ParentFragment
的地方不应为空,但有时,我会随机得到kotlin.UninitializedPropertyAccessException:lateinit属性myData尚未初始化
当我使用 myData
我的 ViewModel 是否可能不保留 myData
?我如何确定我的属性已初始化?
更新:尝试 1
我已经在我的 ParentFragment
中尝试过此代码:
open class ParentFragment : Fragment {
val model : MyViewModel by activityViewModels()
lateinit var backingData : CustomClass
val myData : CustomClass
get() {
if (!::backingData.isInitialized)
model.getData()?.let {
backingData = it
}
return backingData
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.getData?.let {
backingData = it
}
}
}
但是当我调用myData
时,问题并没有消失,似乎是ViewModel
丢失了我的数据
更新 2:更多代码详细信息
在进入扩展 ParentFragment
的 fragment
之前,我在 ViewModel
中设置数据,然后导航到下一个 fragment
如下:
// Inside FirstFragment
if (myData != null) {
model.setData(myData)
findNavController().navigate(FirstFragmentDirections.actionFirstToNextFragment())
}
我的 NavController
有可能在设置数据之前进行导航吗?
编辑3:尝试使用自定义应用程序类
根据下面的答案,我实现了一个自定义应用程序类
,并且我尝试通过此类传递我的对象:
class MyApplication: Application() {
companion object {
var myObject: CustomClass? = null
}
}
但不幸的是,对我来说没有任何改变。也许我的对象太大而无法正确分配?
最佳答案
试试这个:
class MyViewModel : ViewModel() {
var myObject : CustomClass? = null
...
}
open class ParentFragment : Fragment {
lateinit var model : MyViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model = ViewModelProvider(this).get(MyViewModel::class.java)
if(model.myObject == null) {
// initialize myObject, will be persisted by ViewModel
}
}
}
请注意,MyViewModel
及其成员对象不应包含对 Activity
、Fragment
或 Context
,包括对 Context
的任何间接引用,例如 UI View 。
在您的情况下,我不会推荐 LiveData
(或 MutableLiveData
),因为 LiveData
的一个“功能”是它们的值被发布并且异步更新,因此调用 observe
可能为时已晚。
关于java - Fragment 无法从 ViewModel 获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60845217/