The problem is quite straightforward. The question is in context of using ViewModels, LiveData and other related Lifecycle aware arch approaches.
I have an Activity with NavDrawer, which switches fragments inside.
And also I have a case when two fragments are present at the same time on the screen - this will be the main pain.
One Fragment has a ViewPager with nested Fragments
(don't ask why).
The other fragment is just obtaining info from first one when user performs some actions. This is achieved just by sharing activity viewmodel. But the app itself has a lot of business logic and as it goes further the viewmodel goes bigger and bigger.
What I want to ask - not a receipt or rules how to fix this, or maybe how to overcome this by fixing the entire structure of the project. I want to ask for suggestions how can I apply the MVVM approach within android.arch.lifecycle style to mine use-case.
I haven't seen something more complicated then just sharing the Activity ViewModel between Fragments. But common, that's not a cure.
What you can see here - a mess actually. The point is that all are sharing the ActivityViewModel
. Connections(aggregation) from FirstFragment mean that ViewPager
inside FirstFragment
is initiating ChildFragments
and they are also working with the same ActivityViewModel
(kill me). So as result everyone is working with one shared ViewModel.
My proposal is to add a ViewModel for each Layer. So that Activity/Fragments/ChildFragments have their own ViewModels.
But what appears here - how we should communicate then?
Possible solutions :
- Having two ViewModels per one component. One ViewModel will handle/delegate the business logic and another will make the communication. Two viewmodels per component - not so good, yeah?
- Having old manner interface(please no!)
Other workarounds - like DB/SharedPrefs/Realm change listeners and Event Buses(I'm too old for this :( ).
Your solution here!
I'll say that all of the above are breaking a lot of design principles, so what should I do?
How should I come out of this mess? Is there any Uncle Bob
or another superhero
here to help?
P.S. - Well, creating UMLs or other charts isn't mine forte. Sorry for that.
P.P.S. - I'm aware of google samples.
First there is no harm in having multiple
ViewModel
's for a single View.I would think about my ViewModel's like what kind of data is getting and manipulating, and group them in a way, that seems natural.
For your case, if the fragments and the activity's logic is very similar, I think you can go with a single
ViewModel
, but I would avoid that.What I would do is break the activity's
ViewModel
into smaller parts and reuse the properViewModel
's in myFragments
, so that I wouldn't have a God ViewModel, nor roughly the same code in different ViewModel's.What i would suggest you can do is handle two
ViewModel
for your entire use case.Make one
ViewModel
Let's say
MyActivityViewModel
to handle all logic related for activity level. So, if any fragment logic is directly related to your activity then share yourViewModel
like below :&
This will share common
ViewModel
between your activity and fragment.Another
ViewModel
would go forFirstFragment
in your case if you have to share logic between yourChildFragment
:Here you can share
ViewModel
let's sayFragmentViewModel
like below:&
Although, we can still use our activity level
MyActivityViewModel
in our child fragments from FirstFragment like :