0

While discovering the MVVM with Kotlin and Android, I'm facing a small problem related to the organization of one of my fragments.

enter image description here

Suppose I have an activity that hosts a fragment and after a navigation (with NavController) the activity host a new fragment, which has multiples subfragments (perhaps through a ViewPager). All of the 3 fragments (the parent & the 2 children) must display precise part of a data. Furthermore the second subfragment has a button that could change the data & this change must update the UI of all the fragments.

Firstly in my mind, I was thinking all the data will be stored inside the parentFragmentViewModel due to the fact that their will be useful for the 3 fragments, but that's where my problem appeared.

How the subfragments's viewModels could handle these data & update it?

My first thought seems to be incorrect, because if we read the viewModel doc, we can see "However ViewModel objects must never observe changes to lifecycle-aware observables, such as LiveData objects."

So, my subFragments's ViewModels can't observe the parent one. I was thinking about sharing the same viewModel between the 3 fragments but I don't know if it's a bad practice or not and I don't know how to do it the cleanest way possible.

How can I resolve my problem?

EDIT

After further research, I tried this solution https://stackoverflow.com/a/53819347/7861724

I created the viewModel inside the parentfragment. Once done, I get it inside my subfragment.

It currently work but I'm not sure if it's a good practice.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Quentin
  • 486
  • 4
  • 20
  • 1
    for sharing it, it needs to be created in the activity scope. That is what google recommends in the documentation afaik. There is also an extension for achieving it [activityviewmodels](https://developer.android.com/kotlin/ktx) – Blackbelt Jul 29 '20 at 08:02
  • generally, all comm, to be done via host activity but if you have a complicated arch then use eventbus, etc – hemen Jul 29 '20 at 08:05
  • @Blackbelt, ok but if my parentFragment is not the first fragment created by the activity ? Currently, the parentFragment is created by an action of Navigation component. – Quentin Jul 29 '20 at 08:07
  • @notTdat like I said my parentFragment is not the one created at the launch of the activity. I used navigation component and this fragment is created after the execution of an action. Use the activity to do the comm could be problematic if the current fragment is not the one I talk in my question ? – Quentin Jul 29 '20 at 08:09

1 Answers1

0

Why do you need to observe any lifecycle-aware component? You can create setters for MutableLiveData in your ViewModel if you need to update it from he newly created fragments, this doesn't mean that the ViewModel is observing changes.

val data: MutableLiveData<String>
fun updateData(val newData: String) {
    data.value = newData
}

The fragments can actually listen to changes from the ViewModel, but that's fine because in the moment they are destroyed, the observers will also stop observing. That means that you can have your buttons and everything updated with no memory leaks.

  • Thanks for taking time to write an anwser. My problem is, the data that I want to update is in "ParentFragment"'s viewModel and the button that must do the update is in "SubFragment2". So my question is, how to make the "SubFragment2" access the data of his parent viewModel to display & manipulate them ? – Quentin Jul 29 '20 at 10:06
  • 1
    Ah in that case the solution that you tried in the EDIT block should be ok. I would just use requireParentFragment() instead of calling direcly getParentFragment(). The first one checks for you whether the parent is present, ottherwise it throws an IllegalStateException. – Marcos Candela Boti Jul 30 '20 at 11:34
  • Thanks for your review, I've already changed the link code by your recommandation :D – Quentin Jul 30 '20 at 11:36