My app consists of one single Activity
with multiple Fragments
, following the "single Activity app model", so that I can implement properly navigation using the Navigation Component
in Android jetpack
.
Most of my screens (Fragments
) are standalone and don't depend on each other, hence they use their own ViewModel
Some features require navigation involving more than one Fragment
. As those features share data between them that are passed back and forth through the Fragments
, I use a shared ViewModel (as recommended by Google).
I need to use the same instance of the shared ViewModel
in all the associated Fragments
, as I need the Fragments
share the state of the shared ViewModel
.
To use the same instance of the ViewModel
in these associated Fragments
, I need to create the ViewModel
using the parent Activity
(not the Fragment
) when getting the ViewModel
from the ViewModelProviders
:
val viewModel = ViewModelProviders.of(
parentActivity, factory.create()
).get(SharedViewModel::class.java)
This works, however, It produces one problem:
when navigating a consecutive times to the first Fragment
that requires the shared ViewModel
, ViewModelProviders.of()
will return the same instance of the ViewModel
as before: The ViewModel
is being shared between the Fragments
, but also between different navigations to the feature implemented like this.
I understand why this is happening (Android is storing the ViewModel in a map
, which is being used when requesting the ViewModel
with ViewModelProviders.of()
), but I don't know how I am expected to implement the "shared ViewModel pattern" properly.
The only workarounds I see are:
- Create a different
Activity
for the feature that uses theFragment
with a sharedViewModel
- Use nested
Fragments
, and use common parentFragment
for the feature that uses theFragment
with a sharedViewModel
With these two options, I would be able to create a ViewModel
that will be shared between the Fragments
intervening in the feature, and will be different each time I navigate to the feature.
The problem I see here is that this seems to be that against the fundamentals of the Navigation Component
and the single Activity
app.
Each feature implemented this way will need to have a different navigation graph, as they will use a different navigation host. This would prevent me from using some of the nice features of Navigation Component
.
What is the proper way to implement what I want? Am I missing anything, or is it the way it is?
Before Navigation Component
I would use different Activities
and Fragments
and use Dagger
scopes associated with the Activity
/Fragment
to achieve this. But I'm not sure what's the best way of implementing this with just one Activity`