Quick solution without having to use Navigation Component library:

getActivity().getViewModelStore().clear();

This will solve this problem without incorporating the Navigation Component library. It’s also a simple one line of code. It will clear out those ViewModels that are shared between Fragments via the Activity


If you check the code here you'll find out, that you can get the ViewModelStore from a ViewModelStoreOwner and Fragment, FragmentActivity for example implements, that interface.

Soo from there you could just call viewModelStore.clear(), which as the documentation says:

 /**
 *  Clears internal storage and notifies ViewModels that they are no longer used.
 */
public final void clear() {
    for (ViewModel vm : mMap.values()) {
        vm.clear();
    }
    mMap.clear();
}

N.B.: This will clear all the available ViewModels for the specific LifeCycleOwner, this does not allow you to clear one specific ViewModel.


As OP and Archie said, Google has given us the ability to scope ViewModel to navigation graphs. I will add how to do it here if you are using the navigation component already.

You can select all the fragments that needs to be grouped together inside the nav graph and right-click->move to nested graph->new graph

now this will move the selected fragments to a nested graph inside the main nav graph like this:

<navigation app:startDestination="@id/homeFragment" ...>
    <fragment android:id="@+id/homeFragment" .../>
    <fragment android:id="@+id/productListFragment" .../>
    <fragment android:id="@+id/productFragment" .../>
    <fragment android:id="@+id/bargainFragment" .../>

    <navigation 
        android:id="@+id/checkout_graph" 
        app:startDestination="@id/cartFragment">

        <fragment android:id="@+id/orderSummaryFragment".../>
        <fragment android:id="@+id/addressFragment" .../>
        <fragment android:id="@+id/paymentFragment" .../>
        <fragment android:id="@+id/cartFragment" .../>

    </navigation>

</navigation>

Now, inside the fragments when you initialise the viewmodel do this

val viewModel: CheckoutViewModel by navGraphViewModels(R.id.checkout_graph)

if you need to pass the viewmodel factory(may be for injecting the viewmodel) you can do it like this:

val viewModel: CheckoutViewModel by navGraphViewModels(R.id.checkout_graph) { viewModelFactory }

Make sure its R.id.checkout_graph and not R.navigation.checkout_graph

For some reason creating the nav graph and using include to nest it inside the main nav graph was not working for me. Probably is a bug.

Source: https://medium.com/androiddevelopers/viewmodels-with-saved-state-jetpack-navigation-data-binding-and-coroutines-df476b78144e

Thanks, OP and @Archie for pointing me in the right direction.