There are two Fragments: ParentFragment and ChildFragment.
ChildFragment
has been added to a view of the ParentFragment
.
Now using Dagger2
for Android has the ParentFragmentModule
with a method:
@Provides
fun provideViewModel(fragment: ParentFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
Where MyViewModelFactory, MyViewModel, MyViewModelImpl are simple ViewModel logic created in the app.
And the ChildFragmentModule has the method:
@Provides
fun provideViewModel(fragment: ChildFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
This obviously is creating two separate instances of the ViewModel
as they receive two different fragment instances.
How do we make it return the same instance so that the data can be shared between both the Parent and Child fragments?
I have tried passing the ParentFragment
instead of ChildFragment
in the ChildFragmentModule
, but that leads to Dagger dependancy injection error.
Create your ViewModel
with Activity
scope. Then all Fragment
within that Activity
will get same ViewModel
instance.
Check official ViewModelProviders reference. You can create ViewModel
with both Activity
and Fragment
scope.
ViewModelProvider of (FragmentActivity activity)
Creates a ViewModelProvider, which retains ViewModels while a scope of given Activity is alive. More detailed explanation is in ViewModel.
and
ViewModelProvider of (Fragment fragment)
Creates a ViewModelProvider, which retains ViewModels while a scope of given fragment is alive. More detailed explanation is in ViewModel.
Sample code for creating ViewModel
From Activity:
movieListViewModel = ViewModelProviders.of(this).get(MovieListViewModel.class);
From Fragment:
movieListViewModel = ViewModelProviders.of(getActivity()).get(MovieListViewModel.class);
Using Fragment-ktx we can do as In **ParentFragment**
private val viewModel: DemoViewModel by viewModels()
And
In ChildFragment
private val viewModel: DemoViewModel by viewModels(
ownerProducer = { requireParentFragment() }
)
Doing this we can get same instance of ViewModel in Parent Fragment and ChildFragment
add dependencies in app -> build.gralde
implementation 'androidx.fragment:fragment-ktx:1.1.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With