РЕДАКТИРОВАТЬ: в окончательном выпуске AndroidX-Activity 1.2.0
и AndroidX-Fragment 1.1.0
, они сделали SavedStateViewModelFactory
фабрикой по умолчанию в AppCompatActivity / Fragment, поэтому нет необходимости переопределять фабрику по умолчанию (которая является что делает вторая половина этого ответа.)
Обновление и затем использование
class MyViewModel(val savedStateHandle: SavedStateHandle): ViewModel()
class MyAndroidViewModel(application: Application, val savedStateHandle: SavedStateHandle): AndroidViewModel(application)
Должно просто сработать.
ОРИГИНАЛ:
как мне изменить вызов во фрагменте (строка B1 в примере кода)? Нужен ли явный вызов фабрике SavedStateViewModelFactory? Как именно это будет выглядеть?
В AndroidX-Activity 1.2.0 они добавили новый метод под названием getDefaultViewModelProviderFactory()
:
+ @NonNull
+ @Override
+ public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
+ if (getApplication() == null) {
+ throw new IllegalStateException("Your activity is not yet attached to the "
+ + "Application instance. You can't request ViewModel before onCreate call.");
+ }
+ return ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication());
+ }
+
, который означает, что если у меня есть BaseActivity
или BaseFragment
, я могу поменять его на SavedStateViewModelFactory
с viewmodel-savedstate
:
class BaseActivity: AppCompatActivity() {
override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory =
SavedStateViewModelFactory(application, this, intent?.extras ?: Bundle())
}
class BaseFragment: Fragment() {
override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory =
SavedStateViewModelFactory(requireActivity().application, this, arguments ?: Bundle())
}
Как только у вас есть это, вы можете положиться на автомат c создание экземпляра ViewModel с SavedStateHandle
в качестве одного из аргументов:
class MyViewModel(val savedStateHandle: SavedStateHandle): ViewModel()
class MyAndroidViewModel(application: Application, val savedStateHandle: SavedStateHandle): AndroidViewModel(application)
Остерегайтесь того, что порядок application, savedStateHandle
ожидается SavedStateViewModelFactory
.
Однако, если вам нужно пользовательские аргументы в довершение всего, тогда вам нужно будет указать object: AbstractSavedStateViewModelFactory
при вызове метода ViewModelProvider(viewModelStoreOwner).get(...)