如何使用Android DataBinding库保持用户对屏幕方向的输入变化?

mas*_*hin 5 android android-layout android-databinding

我正处于新Android项目的最开始阶段.在我上一个项目中使用MVP之后,我想这次使用Data Binding实现MVVM.

当涉及到屏幕方向更改等配置更改时,我无法正确理解DataBinding.

那里的所有DataBinding示例(我在寻找"android mvvm数据绑定"时找到的所有)都有同样的问题:当我在EditText中输入内容并旋转屏幕时,EditText之后是空的.

一旦我的布局中出现类似下面的内容,我就无法获得视图(本例中为EditText)以在屏幕旋转更改后恢复其状态.

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="vm"
            type="com.example.app.TestViewModel" />
    </data>

    <EditText android:id="@+id/question"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@={vm.question}" 
        android:hint="Question" />

</layout>
Run Code Online (Sandbox Code Playgroud)

我想这是因为每次都在活动onCreate方法中分配一个新的视图模型实例.

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_test);
    binding.setVm(new TestViewModel());
}
Run Code Online (Sandbox Code Playgroud)

你是如何正确处理的?

我无法开发具有多种形式的应用程序,这些形式会在屏幕方向上忘记所有用户输入

Bla*_*der 17

双向数据绑定实际上与自动视图状态恢复兼容,但要使其工作,您需要在恢复视图状态之前应用绑定.

默认情况下,数据绑定会延迟所有绑定,直到下一个布局传递,这在视图状态恢复后发生.这意味着视图状态实际上将被恢复,但随后绑定值将覆盖视图的当前值.

要立即应用绑定,请executePendingBindings()在恢复视图状态之前调用,例如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();
}
Run Code Online (Sandbox Code Playgroud)

这就是你需要做的一切.当然,视图需要具有android:id属性才能自动保存和恢复其状态.

恢复视图状态后,还将使用双向绑定将已还原的值分配给绑定的属性,以便ViewModel将反映恢复的状态.


XII*_*-th 3

您需要通过重写onSaveInstanceState()活动类中的方法来保存视图模型的状态并在onCreate()方法中恢复它。

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);
}
Run Code Online (Sandbox Code Playgroud)

有关“保存-恢复”技术的更多信息,您可以阅读这部分文档