-
Notifications
You must be signed in to change notification settings - Fork 500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scope ViewModel to NavBackStackEntry jetpack compose #606
Comments
After reading the documentation, I came up with this extension function. @OptIn(InternalMavericksApi::class)
@Composable
inline fun <reified VM : MavericksViewModel<S>, reified S : MavericksState> composeMavericksViewModel(
scope: LifecycleOwner = LocalLifecycleOwner.current,
noinline keyFactory: (() -> String)? = null,
noinline argsFactory: (() -> Any?)? = null,
): VM {
val activity = extractActivityFromContext(LocalContext.current)
checkNotNull(activity) {
"Composable is not hosted in a ComponentActivity!"
}
val viewModelStoreOwner =
scope as? ViewModelStoreOwner ?: error("LifecycleOwner must be a ViewModelStoreOwner!")
val savedStateRegistryOwner = scope as? SavedStateRegistryOwner
?: error("LifecycleOwner must be a SavedStateRegistryOwner!")
val savedStateRegistry = savedStateRegistryOwner.savedStateRegistry
val viewModelClass = VM::class
val view = LocalView.current
val viewModelContext = remember(scope, activity, viewModelStoreOwner, savedStateRegistry) {
val parentFragment = findFragmentFromView(view)
if (parentFragment != null) {
val args = argsFactory?.invoke() ?: parentFragment.arguments?.get(Mavericks.KEY_ARG)
FragmentViewModelContext(
activity,
args,
parentFragment,
owner = viewModelStoreOwner,
savedStateRegistry = savedStateRegistry
)
} else {
val args = argsFactory?.invoke() ?: activity.intent.extras?.get(Mavericks.KEY_ARG)
ActivityViewModelContext(activity, args, viewModelStoreOwner, savedStateRegistry)
}
}
return remember(viewModelClass, viewModelContext) {
MavericksViewModelProvider.get(
viewModelClass = viewModelClass.java,
stateClass = S::class.java,
viewModelContext = viewModelContext,
key = keyFactory?.invoke() ?: viewModelClass.java.name
)
}
} The only change is this FragmentViewModelContext(
activity,
args,
parentFragment,
owner = viewModelStoreOwner,
savedStateRegistry = savedStateRegistry
) Instead of using the |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am currently integrating jetpack compose into an existing project. For this, I have a fragment that hosts two composables. One is the category screen and the other is the products list present in that category as navigation destinations. This is the code within fragment's
onCreateView
.In
AdminProductScreen
I'm getting the viewModel using thisFrom the documentation
So I expect the
viewModel
to be cleared when the composable is popped but this is not the case. When I press the back button and navigate to another product page with a different category id, I can see the products from the previous category.Looking at the source code for
mavericksViewModel()
and debugging it, theviewModelContext
isFragmentViewModelContext
.I have even tried passing the
NavBackStackEntry
asscope
but still the result is the same. I don't see theviewModelStoreOwner
being used in theFragmentViewModelContext
. Am I missing something? Any help would be appreciated. Thank you.I am using dagger for dependency injection.
In VM
Dagger Module
There are some changes in the navigation library with the recent updates. I'm currently using navigation
2.4.0-rc01
and compose1.1.0-rc01
.The text was updated successfully, but these errors were encountered: