Possible solution for Arch ViewModel dynamic parameters
See original GitHub issueAfter seeing Jake’s presentation on this library at DroidCon, I was hoping that the proposed solution will solve the problem of passing dynamic parameters to Android Architecture Components ViewModel that is discussed on several places over the internet, originally probably here https://github.com/googlesamples/android-architecture-components/issues/207
Since ViewModel shouldn’t be injected directly to a client as Presenter is in the examples of this library and Jake’s talk, all I could come up with was double factories, the assisted factory for creating ViewModelFactory and then then ViewModelFactory to have the system lazily create the ViewModel.
Can someone see a better solution or would it require a specific fork of this library to auto generate this extra ViewModelFactory?
Ideally I would see the same solution as in Jake’s presentation. No manual creation of ViewModel and no manual parameter passing, only the dynamic params to Factory create method.
My example: The ViewModelFactory and “ViewModelFactoryFactory”
class WordDetailViewModelFactory @AssistedInject constructor(
private val repository: WordRepository,
@Assisted private val argument: WordDetailScreenArg
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return WordDetailViewModel(repository, argument) as T
}
@AssistedInject.Factory
interface Factory {
fun create(argument: WordDetailScreenArg): WordDetailViewModelFactory
}
}
The ViewModel
class WordDetailViewModel(
private val repository: WordRepository,
argument: WordDetailScreenArg
) : ViewModel() {
val wordDetail: LiveData<Word> = repository.word(argument.word)
fun onDeleteWordClicked() {
wordDetail.value?.let {
repository.deleteWord(it.word)
}
}
}
Injection
@Inject
lateinit var viewModelFactory: WordDetailViewModelFactory.Factory;
override fun onAttach(context: Context?) {
super.onAttach(context)
val arguments: WordDetailScreenArg = ...
Injection.appComponent.inject(this)
viewModel = ViewModelProviders.of(this, viewModelFactory.create(arguments))[WordDetailViewModel::class.java]
}
Edit: looks like @hansenji has a solution at https://github.com/hansenji/ViewModelInject
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:12 (2 by maintainers)
This functionality is going to be covered by the upcoming Hilt tool in Jetpack which integrates Dagger with view models and work manager.
This library uses Assisted Inject and SavedStateHandle to pass arguments into your viewmodel https://github.com/hansenji/ViewModelInject.