Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scoping a viewmodel to multiple fragments (not activity) using the navigation component

Tags:

I'm using the navigation component, I want a view model to be shared between a few fragments but they should be cleared when I leave the fragments (hence not scoping them to the activity) I'm trying to take the one activity many fragments approach. I have managed to achieve this using multiple nav hosts and scoping the fragments to it using getParentFragment but this just leads to more issues having to wrap fragments in other parent fragments, losing the back button working seamlessly and other hacks to get something to work that should be quite simple. Does anyone have a good idea on how to achieve this? I wondered if theres anything with getViewModelStore I could be using, given the image below I want to scope a view model to createCardFragment2 and use it in anything after it (addPredictions, editImageFragment, and others i haven't added yet), but then if I navigate back to mainFragment I want to clear the view models.

BTW I cant just call clear on mainFragment view model store as there are other view models here that shouldn't be cleared, I guess i want a way to tell the nav host what the parent fragment should be which I'm aware isn't going to be a thing, or a way to make the view model new if I'm navigating from mainFragment or cardPreviewFragment

nav graph

like image 915
martinseal1987 Avatar asked Jun 08 '19 10:06

martinseal1987


People also ask

Can multiple fragments share a ViewModel?

Multiple fragments in the app will access the shared ViewModel using their activity scope. It is a common use case to share data between fragments in most production apps.

How do I pass ViewModel between fragments?

In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.

What is the scope of ViewModel?

The ViewModel instance is handled by an internal Android factory, allowing it to survive configuration changes. Similar Dagger Hilt, there is a special scope to survive configuration changes. The activityRetainedScope() function will hold instances via a ViewModel holder instance for you.

What is navGraphViewModels?

navGraphViewModels is a kotlin extension function for fragments that creates nav graph scoped view models. It accepts two parameters: a nav graph ID and also a viewmodel factory. You can simply write: Val order selection by navGraphViewModels(R. id.


1 Answers

Here's a concrete example of Alex H's accepted answer.

In your build.gradle (app)

dependencies {     def nav_version = "2.1.0"     implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" } 

Example of view model

class MyViewModel : ViewModel() {      val name: MutableLiveData<String> = MutableLiveData() } 

In your FirstFlowFragment.kt define

val myViewModel: MyViewModel by navGraphViewModels(R.id.your_nested_nav_id) myViewModel.name.value = "Cool Name" 

And in your SecondFlowFragment.kt define

val myViewModel: MyViewModel by navGraphViewModels(R.id.your_nested_nav_id) val name = myViewModel.name.value.orEmpty() Log.d("tag", "welcome $name!") 

Now the ViewModel is scoped in this nested fragment, shared state will be destroyed when nested nav is destroyed as well, no need to manually reset them.

like image 115
Miko Chu Avatar answered Sep 23 '22 11:09

Miko Chu