#android #android-fragments #android-viewmodel
#Android #android-фрагменты #android-viewmodel
Вопрос:
В этом видео (MVVM и вложенные фрагменты / просмотры: контракты ViewModel — автор Маркос Пауло Дамескено, Брет Эриксон 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
Переданный в качестве параметра является an Activity
, но если у меня есть Fragment
внутри другого Fragment
, где оба они имеют одинаковое ViewModel
значение, ViewModel
возвращаемый by viewModelContracts()
будет отличаться от объекта, созданного родительским 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()
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
}