Android 数据绑定 - 视图在旋转时松开绑定

Android Data Binding - View Looses Binding When Rotated

我正在创建一个应用程序,它是一个专门的计时器。我正在展示一个倒计时计时器以及在倒计时期间做一些其他事情。来自 MVVM 背景,我想为这个项目使用新的 Android 绑定框架。我按照示例设置我的视图:

<data>
    <variable
        name="viewModel"
        type="com.examples.viewmodels.MainActivityVM"/>
</data>

用一个 TextView 来显示倒计时。

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@{viewModel.timeLeftText}"
        android:textAlignment="center"
        android:textSize="144dp"/>

class activity 我已经在 onCreate 覆盖中设置了绑定:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setViewModel(this.viewModel);
}

一切都像宣传的那样有效。我可以单击视图上的按钮并开始倒计时。我编写的业务逻辑 class 处理用剩余时间更新视图模型实例和视图更新,正如我所期望的那样。太棒了!

但是,我 运行 遇到一个问题,如果设备从纵向旋转到横向,视图将完全失去与视图模型的连接。奇怪的是,它会回到默认启动状态,就好像应用程序刚刚第一次启动一样。

我突然想到,在某些情况下,应用程序可能会暂停,然后根据更改恢复。我通过查看 Google 验证了它,发现应用程序可以在方向改变时暂停和恢复。我将清单中的 activity 更改为:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation"
    android:label="@string/app_name">
...
</activity>

这没有帮助。我错过了什么? (可能很多!)

首先,Android activity 总是在其方向改变时被销毁并重新创建。用你的话说What's odd is that it goes back to its default start state as if the app has just started for the first time。这没什么奇怪的,事实上它明确提到 here.

如果您希望 Android 系统不重新创建 activity,您可以使用

android:configChanges="orientation|screenSize"

您的代码不起作用的原因可能是您的目标是 API 13+ 级,如前所述 here

Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the "screenSize" value in addition to the "orientation" value. That is, you must decalare android:configChanges="orientation|screenSize". However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).