Shared viewModel with assisted injection and hilt
I have an activity. This activity is receiving some arguments.
At the moment, I'm able to create a viewModel
with those parameters with assisted injection.
//activity code
private val viewModel: ViewModel by viewModels {
val keyName = intent.extras?.getString(KEY_NAME).orEmpty()
ViewModel.provideFactory(keyName)
}
Now, I have a navHostFragment
and all the fragments in the nav graph will use the viewModel I created before in the activity.
But I can't find a way share that viewModel
I already know we can use activityViewModels
to share the viewModel with the activity
//fragment code
private val sharedViewModel: ViewModel by activityViewModels()
But my sharedViewModel
doesn't have a constructor without assisted arguments (and fails in runtime).
At the moment, I have two solutions
First option: "create" a new viewModel in each fragment and receive the arguments from the activity (or navArgs) using activityViewModels to share the same instance (I didn't like this approach, but works)
private val viewModel: ViewModel by activityViewModels {
val keyName = navArgs.keyName
ViewModel.provideFactory(keyName)
}
Second option: Remove the assisted arguments from the constructor and create a method in the viewModel to set the information I need:
@HiltViewModel
class ViewModel @Inject constructor(
private val repository,
.....
) : ViewModel() {
fun setKeyName(keyName: String)....
So, my question is... is there a way to create a viewModel in the activity, with assisted arguments, and share that viewModel with the fragments?
With hilt library now supports view model which takes SavedStateHandle
as parameter and values are passed with SavedStateHandle
automatically. All you have to do is receive the value in the following way
@HiltViewModel
class ViewModel @Inject constructor(
private val repository, savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
// Use the same argName as in your navigation graph
val name : String = savedStateHandle["keyName"]
}