Search code examples
androidandroid-studioandroid-viewmodelandroid-architecture-navigationandroid-navigation

Shared View Model between two fragments in the nav_graph


I have an app with one activity and about 29 Fragment in the nav_graph, two of these fragments are used for authentication, and I need to share data between these two fragments using a shared view model but not with the other fragments.

So, I created my ViewModel and instantiated it in both fragments using the viewModels() which is a part of fragment-ktx library.

private val viewModel: AuthViewModel by viewModels()

However, once I navigate to the second fragment using the findNavController().navigate() I lose all the data in the AuthViewModel

AuthViewModel.kt

class AuthViewModel @ViewModelInject constructor(
    private val authRepository: AuthRepository
) : BaseViewModel()

Is there any additional step I'm missing here?

EDIT

I'm accessing the data from the onViewCreated method


Solution

  • When you create a viewmodel by viewmodels() yout get a reference to the ViewModel scoped to the current Fragment.

    So in your case you would be using private val viewModel: AuthViewModel by viewModels() in both the fragment which gives you two different instance of viewmodel tied to each fragment.

    The concept of Shared Viewmodel need a Shared Scope like Activity or NavGraph.

    1. Using Activity

    Just change

    private val viewModel: AuthViewModel by viewModels()
    

    to

    private val viewModel: AuthViewModel by activityViewModels()
    
    1. Using NavGraph

    Create another nav graph where you have two fragments which are used for authentication.

    <navigation android:id="@+id/authenticationNavGraph" 
            app:startDestination="@id/chooseRecipient">
            <fragment
                android:id="@+id/authentication1Fragment"
                android:name="com.example.AuthFragment1"
                android:label="Fragment 1">
            </fragment>
            <fragment
                android:id="@+id/authentication2Fragment"
                android:name="com.example.AuthFragment2"
                android:label="Fragment 2" />
    </navigation>
    

    Now If you want to use same viewmodel AuthViewModel then you can create a viewmodel using:

    private val viewModel: AuthViewModel by navGraphViewModels(R.id.authenticationNavGraph)