I have an architectural question about the android ViewModels:
Let's say that in my App I have an Activity with two Fragments inside (using a Viewpager). The two fragments do different things (therefore may have their own ViewModel?), but they also both need various data that is similar.
This is for example the state if a network connection is available or not (and both fragments show different error UIs if there is no connection), or some user setting that comes via a Push from a server and affects both fragments equally.
This looks something like this:
Now my question is how to deal with that situation when using ViewModels? Is it good that a view observes multiple ViewModels, like it would be if I have a ViewModel for the Activity (holding the state that both need equally) and one for each fragment, like this:
This was hinted here for example, but it is not a good practice, as the relationship in MVVM generally is
View n - 1 ViewModel n - 1 Model
But I am not sure where the right place for such shared LiveData is in my case?
I think the concept behind the ViewModel was that it is supposed to be related to a single "Screen" rather than a "View". So going by that logic, I think you can use the same ViewModel if multiple fragments reference the same ViewModel because they technically belong to the same "Screen".
In the fragments, you could request the activity for the ViewModel which holds the instance of LiveData and could give you the updates as needed.
Hope this answers your question.
Update: I found a link to a sample fragment in Google samples. Check out onCreateView() method. Pasting code below for reference:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.addtask_frag, container, false);
if (mViewDataBinding == null) {
mViewDataBinding = AddtaskFragBinding.bind(root);
}
mViewModel = AddEditTaskActivity.obtainViewModel(getActivity());
mViewDataBinding.setViewmodel(mViewModel);
setHasOptionsMenu(true);
setRetainInstance(false);
return mViewDataBinding.getRoot();
}
P.S. If you have found a better solution/answer/practice, lemme know.