I have a ViewModel
I am currently using to contain data and share values between Fragments. This model also helps instantiate the data for the app on activity start.
I am now trying to add in state saving functionality to my app, and I'm confused on how to merge the two systems together. The android docs mention to use this constructor:
public MyViewModel(SavedStateHandle savedStateHandle) {
mState = savedStateHandle;
}
However, I'm unsure on how the state is passed and how this constructor is used in activities (here is my usage):
myViewModel = new ViewModelProvider(requireActivity()).get(myViewModel.class);
Anyway, since I need to also instantiate data in case the savedState is null, I'm not sure how that part fits in. For reference, here is a general outline of my ViewModel class:
public class myViewModel extends ViewModel {
// private MutableLiveData<Integer> foo; <-- obsolete with state saving
private SavedStateHandle mState;
private static final String FOO_KEY = "foo";
// Do I need this anymore? How do I combine this with the other constructor?
public myViewModel() {
foo = new MutableLiveData<>();
foo.setValue(4);
}
// Constructor for the savedStateHandle
public myViewModel(SavedStateHandle savedStateHandle) { mState = savedStateHandle; }
LiveData<Integer> getFoo() { return mState.getLiveData(FOO_KEY); }
void setFoo(int foo) { mState.set(FOO_KEY, foo); }
}
Obviously if I take out the old constructor and MutableLiveData
member, then when I access the ViewModel in my fragments, the data will be null (because I haven't told the activity to explicitly save a state yet), and I haven't instantiated any data.
You don't need your no argument constructor. Instead, you should use the other getLiveData()
method that takes an initial value:
public class myViewModel extends ViewModel {
private SavedStateHandle mState;
private static final String FOO_KEY = "foo";
public myViewModel(SavedStateHandle savedStateHandle) {
mState = savedStateHandle;
}
LiveData<Integer> getFoo() {
// Get the LiveData, setting the default value if it doesn't
// already have a value set.
return mState.getLiveData(FOO_KEY, 4);
}
void setFoo(int foo) { mState.set(FOO_KEY, foo); }
}