I\'m at the very beginning of a new Android project. After playing around with MVP in my last project, I want to implement MVVM with Data Binding this time.
I have a
The correct answer is below, see: https://stackoverflow.com/a/46086436/4848192
ViewModels should outlive configuration changes.
With the new architecture components you could easily implement this:
public class TestViewModel extends ViewModel{
...
}
Then in your Activity#onCreate(...)
:
public class MainActivity extends LifecycleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_test);
ViewModelProvider provider = ViewModelProviders.of(this);
binding.setVm(provider.get(TestViewModel.class));
}
}
You need to save state of your view model by overriding of method onSaveInstanceState()
in your activity class and restore it in onCreate()
method.
private static final String QUESTION = "testViewModel.question";
private TestViewModel mTestViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_test);
mTestViewModel = new TestViewModel();
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// restore view model state
String questionVal = savedInstanceState.getString(QUESTION, "");
mTestViewModel.setQuestion(questionVal);
}
binding.setVm(mTestViewModel);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save current view model state
savedInstanceState.putString(QUESTION, mTestViewModel.getQuestion());
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
More information about "save-restore" technology you can read at this part of documentation
Two-way data binding is actually compatible with automatic view state restoration, but for it to work you need to apply the binding before the view state is restored.
By default, data binding defers all bindings until the next layout pass, which occurs after the view state has been restored. This means the view state will actually be restored, but then the binding value(s) will overwrite the current values of the views.
To apply binding immediately, call executePendingBindings()
before the view state is restored, for example in Activity.onCreate()
:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_test);
viewModel = new TestViewModel();
binding.setVm(viewModel);
binding.executePendingBindings();
}
And that's all you need to do. Of course, the views need to have an android:id
attribute in order for their state to be saved and restored automatically.
When the view state is restored, the restored values will also be assigned to the properties bound using two-way binding so your ViewModel will reflect the restored state.