Распространенная задача — при создании viewModel требуется передать параметры из активити или фрагмента.
ViewModel используется для хранения состояния данных экрана, отвечая только за т.н. бизнес логику. Жизненный цикл этого компонента не зависит от изменения конфигурации экрана (поворот экрана), потому он довольно стойко переносит все трансформации, сохраняя данные для активити.
При этом самый простой способ инициализации модели заключается в вызове ViewModelProvider без указания параметров, которые мы хотели бы передать, т.к. мы указываем только имя нашего класса, который был создан на базе ViewModel (или AndroidViewModel).
1 2 |
val context = ... val viewModel = ViewModelProvider(context).get(MyViewModel::class.java) |
ViewModelProvider имеет также перегруженный конструктор, где дополнительно к контексту передаётся фабрика созданная на базе ViewModelProvider.Factory. Параметры можно передать, создав собственную фабрику для вашей модели(-ей).
Типичный пример реализации выглядит вот так:
1 2 3 4 5 6 7 8 |
class MyViewModelFactory(private val param: Int): ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MyViewModel::class.java)) { return MyViewModel(param) as T } throw RuntimeException("...") } } |
А при инициализации экземпляра вы должны использовать эту фабрику для передачи параметров (в примере у нас только один — param: Int).
1 2 3 4 5 6 7 8 |
// к примеру, контекст - это наша активити Main val context = MainActivity@this val param: Int = ... val viewModel = ViewModelProvider( context, MyViewModelFactory(param) ) .get(MyViewModel::class.java) |