I am trying to wrap my head around the new Android Architecture Components, specifically the ViewModel.
My impression is that a Fragment should not know about what Activity or Fragment it is owned by, so that it can be used in different contexts of the application. The examples seem to contradict this by declaring the ViewModel scope directly in the Fragment, rather than the Fragment owner:
viewModel = ViewModelProviders.of(getActivity()).get(SomeViewModel.class);
I would like to be able to use this Fragment in a Master/Detail configuration, where both share the same state (i.e. ViewModel instance), as well as inside a ViewPager, where all Fragments require separate state (i.e. separate ViewModel instances). I would expect the Fragment owner to dictate the scope, which does not seem to be supported with this approach.
A workaround I came up with could be to optionally pass in a configured ViewModelProvider to explicitly broaden the scope of a ViewModel if necessary (e.g. in the Master/Detail configuration) and have separate ViewModels by default:
final ViewModelProvider viewModelProvider;
if (viewModelProviderOverride != null) {
viewModelProvider = viewModelProviderOverride;
} else {
viewModelProvider = ViewModelProviders.of(this);
}
viewModel = viewModelProvider.get(SomeViewModel.class);
This way, the owner can decide whether multiple Fragments will share their state or not. I haven't fully thought this through yet, but it seems kind of fishy, since nothing close to it seems to be hinted at in the docs. I feel like I am missing something obvious.
A ViewModelScope is defined for each ViewModel in your app. Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared. Coroutines are useful here for when you have work that needs to be done only if the ViewModel is active.
Passing Data between fragments in Android using ViewModel: This is because ViewModel is tied to the activity lifecycle. To actually pass the data between fragments, we need to create a ViewModel object with an activity scope of both the fragments, initialize the ViewModel , and set the value of the LiveData object.
ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way.It is the main component in the MVVM architecture. ViewModel can be created with activity context or fragment context. When a ViewModel object is created, it is stored inside Activity OR FragmentManager.
Lifecycle Awareness: ViewModel objects are also lifecycle-aware. They are automatically cleared when the Lifecycle they are observing gets permanently destroyed.
Saying viewModel = ViewModelProviders.of(getActivity()).get(SomeViewModel.class);
means that you would like the state of the ViewModel
to be scoped to the Activity. If you would not like the Fragment to be scoped to the activity you can just call viewModel = ViewModelProviders.of(this).get(SomeViewModel.class);
. Now all you do is if (shareState)
then call the first and if not call the second.
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