2

I'm using single activity pattern and in one particular screen, I want to share one viewModel with two different fragments. After researching for a bit, I found these solutions:

  1. I use the activity instance whilst creating the viewModel, so that both of my fragments get the same instance. but the drawback with this approach would be, that the viewModel instance will be alive till the application is running.
ViewModelProviders.of(Activity.this, viewModelFactory).get(CustomViewModel::class.java)
  1. I can add a Tag to the first fragment while launching it and pass the instance of first fragment while creating viewModel in Second fragment. This way I will have a single instance of ViewModel shared across two fragments. ViewModelProviders.of(fragmentManager?.findFragmentByTag(TAG)!!, viewModelFactory).get(CustomViewModel::class.java)

  2. I read one more method somewhere to share viewModel, but I forgot because it didnt work for me.

I would like to know which method would be the best for sharing viewModel across fragments. What are my options here? Thanks.

Enrico Cortinovis
  • 811
  • 3
  • 8
  • 31
Bheem
  • 189
  • 2
  • 9
  • You've broken the MVVM pattern, the whole point of it is a 1:1 relationship between view models and their corresponding views. – Mark Feldman Nov 30 '19 at 22:02
  • If you are using also navigation components you can scope the viemodel by navigation graph level. – Andre Classen Nov 30 '19 at 22:08
  • Hey @MarkFeldman I understand your point, but it's logical to create a single viewmodel for two different fragments, if both of them are using same data. I also have another screen, where I'm using four fragments. Making four viewModels in that screen doesn't seems a good idea, especially when all of the fragments use same data. Also as per the viewmodel description in https://developer.android.com/topic/libraries/architecture/viewmodel, a single viewmodel can be used to share data b/w fragments. . – Bheem Dec 01 '19 at 14:59
  • Hey @AndreClassen Thanks. I'm not using navigation graph in the application at the moment. Will definitely give it a try after I implement navigation graph. – Bheem Dec 01 '19 at 15:05
  • 1
    It might seem logical, but it's not MVVM. A view is the *declarative* element of your GUI while the view model is the abstraction of that views state; data-binding is what holds them together. If you've got data that has to be represented by multiple views then that should be in your model layer, with multiple view model instances exposing that data to their associated views. There's no way to unit-test that your multiple views are all co-existing peacefully (say) if you don't abstract them out into your view model layer. – Mark Feldman Dec 01 '19 at 20:50

2 Answers2

0

according to the docs here is how you can share the same ViewModel with multiple fragments.

model = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.java]
    } ?: throw Exception("Invalid Activity")

its explained in the docs as below:

Notice that both fragments retrieve the activity that contains them. That way, when the fragments each get the ViewModelProvider, they receive the same SharedViewModel instance, which is scoped to this activity.

[Update] You can use kotlin property delegate in your fragments instead

private val model: SharedViewModel by activityViewModels()

Official docs

Ayoub
  • 493
  • 3
  • 8
0

First of all add these dependencies to activate viewmodel lifecycle delegate:

implementation "androidx.fragment:fragment-ktx:1.3.6"

Then in your fragment class use view model like this :

private val viewmodel: SearchFragmentViewModel by activityViewModels()

if you are using dagger see this

user16728174
  • 182
  • 1
  • 4