android - 如何检查给定 ViewModelProvider 的 ViewModel 是否已存在
问题描述
该视频(MVVM 和嵌套片段/视图:ViewModel 合同 - Marcos Paulo Damesceno,Bret Erickson droidcon 旧金山 2019 年)展示了一种使用ViewModel
.
我出于学习目的而实施它,但我被卡住了。
// 18:35 of the video
private const val VM_KEY = "view_model_contract_key"
fun <T> Fragment.viewModelContracts() = lazy {
val clazz: Class<ViewModel> = arguments?.getSerializable(VM_KEY) as Class<ViewModel>
val viewModelProvider = ViewModelProvider(requireActivity())
return@lazy viewModelProvider.get(clazz) as T
}
传递的ViewModelStoreOwner
as 参数是一个Activity
,但如果我Fragment
在另一个内部有一个Fragment
它们都共享相同ViewModel
的,则ViewModel
返回的viewModelContracts()
对象将是与 Parent 创建的对象不同的对象Fragment
。
interface ChildViewModelContract {
// ...
}
class SomeViewModel : ViewModel(), ChildViewModelContract {
// ...
}
class ParentFragment: Fragment {
private val viewModel: SomeViewModel by viewModels()
// ...
}
class ChildFragment: Fragment {
private val viewModelContract: ChildViewModelContract by viewModelContracts()
// ...
}
理想的解决方案是检查父片段的 是否fun <T> Fragment.viewModelContracts()
存储在其中,如果没有,则使用Activity 的。但我不知道该怎么做。ViewModelProvider
ViewModel
ViewModelProvider
fun <T> Fragment.viewModelContracts() = lazy {
val clazz: Class<ViewModel> = arguments?.getSerializable(VM_KEY) as Class<ViewModel>
val parentFragment = parentFragment
if (parentFragment != null) {
val viewModelProvider = ViewModelProvider(parentFragment)
// is there any way to do something like this?
if (viewModelProvider.isViewModelStored(clazz)) {
return@lazy viewModelProvider.get(clazz) as T
}
}
val viewModelProvider = ViewModelProvider(requireActivity())
return@lazy viewModelProvider.get(clazz) as T
}