Как проверить, существует ли ViewModel уже для данного ViewModelProvider

#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
}