jaqxues
11/01/2020, 2:45 PMviewModel<ViewModelClass>()
function to get a ViewModel in Compose with Hilt/Dagger?
Something that i can use like this
@Composable
inline fun <reified T: ViewModel> viewModel() =
(ContextAmbient.current as MainActivity).viewModels<T>()
@Composable
fun Example() {
val viewModel by viewModel<SomeViewModel>()
viewModel.doStuff()
}
The above works, but it certainly is not elegant or safe or anythingmsfjarvis
11/01/2020, 3:14 PMandroidx.compose.ui.viewinterop.viewModel
not do the job for you?msfjarvis
11/01/2020, 3:15 PMjaqxues
11/01/2020, 3:16 PMjava.lang.RuntimeException: Cannot create an instance of class com.jaqxues.example.viewmodel.SomeViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.compose.ui.viewinterop.ViewModelKt.get(ViewModel.kt:75)
at androidx.compose.ui.viewinterop.ViewModelKt.viewModel(ViewModel.kt:60)
msfjarvis
11/01/2020, 3:20 PMjaqxues
11/01/2020, 3:20 PMmsfjarvis
11/01/2020, 3:20 PMjaqxues
11/01/2020, 3:21 PM@HiltAndroidApp
, ViewModel with @ViewModelInject
, Activity with @AndroidEntryPoint
jaqxues
11/01/2020, 3:22 PMIan Lake
11/01/2020, 3:31 PMviewModel()
inside a NavHost
, which is where you'd need to follow the Hilt docs on using ViewModels with Navigation: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1604071670473700?thread_ts=1604043017.440100&cid=CJLTWPH7Sjaqxues
11/01/2020, 3:51 PMdefaultViewModelProviderFactory
every time to get a viewModel or is there an easier way?
And the navGraphViewModels
is defined for a Fragment, not for a Composable.Ian Lake
11/01/2020, 4:00 PMviewModel()
instance within a NavHost
is creating a ViewModel scoped to your navigation destination, exactly like navGraphViewModels
does. So yes, if you want to use a defaultViewModelProviderFactory
that is tied to your Hilt enabled activity/fragment, you need to specifically say thatjaqxues
11/01/2020, 4:22 PMjaqxues
11/01/2020, 4:54 PMjava.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered
at androidx.savedstate.SavedStateRegistry.registerSavedStateProvider(SavedStateRegistry.java:111)
at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:50)
at androidx.lifecycle.SavedStateHandleController.create(SavedStateHandleController.java:70)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:67)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.compose.ui.viewinterop.ViewModelKt.get(ViewModel.kt:75)
at androidx.compose.ui.viewinterop.ViewModelKt.viewModel(ViewModel.kt:60)
Ian Lake
11/01/2020, 6:28 PMjaqxues
11/01/2020, 6:30 PMIan Lake
11/01/2020, 6:30 PMIan Lake
11/01/2020, 6:30 PMjaqxues
11/01/2020, 6:36 PMIan Lake
11/01/2020, 6:38 PMjaqxues
11/01/2020, 6:38 PMIan Lake
11/01/2020, 8:05 PMdefaultViewModelProviderFactory
stores it's saved state at the activity/fragment layer.
In that issue I linked, the fragment is within the Navigation graph, so the issue is that the saved state is too small of a scope (the navigation graph encompasses multiple fragments).
In your Compose case, the entire navigation graph in within the single activity/fragment, so there the scope is too large and you end up saving state multiple times with the same key.Ian Lake
11/01/2020, 8:06 PMNavHost
, which only happens to work because then your scopes match - it is scoped to the entire Compose hierarchy which is the same as the activity/fragment that hosts itjaqxues
11/01/2020, 8:08 PMIan Lake
11/01/2020, 8:12 PMjaqxues
11/01/2020, 8:13 PMjaqxues
11/01/2020, 8:13 PMIan Lake
11/01/2020, 8:14 PMIan Lake
11/01/2020, 8:15 PMbodo
11/06/2020, 2:22 PMjaqxues
11/06/2020, 2:23 PMbodo
11/06/2020, 2:27 PMjaqxues
11/06/2020, 2:50 PMbodo
11/06/2020, 3:10 PMbodo
11/06/2020, 3:48 PMSaurabhS
11/06/2020, 4:00 PMIan Lake
11/06/2020, 4:26 PMzoha131
12/20/2020, 7:31 PM