简体   繁体   English

旋转设备时如何保存在 ViewModel 中观察到的 UI state?

[英]How to save UI state observed in ViewModel when rotating device?

I have UI displaying details of a place, including some EditTexts and an adapter from this ExpandableRecyclerView library .我有 UI 显示一个地方的详细信息,包括一些 EditTexts 和来自此 ExpandableRecyclerView 库的适配器。

The UI is updated in onCreate when my ViewModel observes a change to the place.当我的 ViewModel 观察到该位置的更改时,UI 会在onCreate中更新。 I save the adapter in onSaveInstanceState and restore it in onRestoreInstanceState .我将适配器保存在onSaveInstanceState并在onRestoreInstanceState中恢复它。

However once I rotate my device, the old UI state is displayed.但是,一旦我旋转我的设备,就会显示旧的 UI state。 For example, I enter some text to the EditText and expand my adapter, but after I rotate my device the old text and collapsed adapter appears.例如,我在 EditText 中输入了一些文本并展开了我的适配器,但在我旋转我的设备后,旧文本和折叠的适配器出现了。 I think this is because adapter is null until onChanged is called, so my adapter method in onRestoreInstanceState is skipped, and EditTexts are re-updated to old text in onChanged .我认为这是因为适配器是 null 直到onChanged被调用,所以我在onRestoreInstanceState中的适配器方法被跳过,并且 EditTexts 被重新更新为onChanged中的旧文本。

How do I save the state of my UI?如何保存我的 UI 的 state?

Full code can be found here .完整的代码可以在这里找到。

onCreate:创建:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        viewModel = new ViewModelProvider(this).get(PlaceViewModel.class);

        Intent intent = getIntent();
        if (intent.hasExtra(EXTRA_PLACE_ID)) {
            String id = intent.getStringExtra(EXTRA_PLACE_ID);


            viewModel.getPlaceById(id).observe(this, new Observer<PlaceModel>() {
                @Override
                public void onChanged(PlaceModel placeModel) {
                    // placeModel will be null if place is deleted
                    if (placeModel != null) {
                        // update UI here
                    }
                }
            });
        }
}

onSaveInstanceState and onRestoreInstanceState: onSaveInstanceState 和 onRestoreInstanceState:

/* To save the expand and collapse state of the adapter,
you have to explicitly call through to the adapter's
onSaveInstanceState() and onRestoreInstanceState() in the calling Activity */
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    if (adapter != null) {
        adapter.onSaveInstanceState(outState);
    }
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (adapter != null) {
        adapter.onRestoreInstanceState(savedInstanceState);
    }
}

One solution is just check if savedInstanceState is null, if it is don't set text of EditTexts and restore adapter state.一种解决方案是检查 savedInstanceState 是否为 null,如果不设置 EditTexts 的文本并恢复适配器 state。

But I didn't carefully read the ViewModel documentation : "The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations."但我没有仔细阅读ViewModel 文档:“ViewModel class 旨在以生命周期意识的方式存储和管理与 UI 相关的数据。ViewModel class 允许数据在屏幕旋转等配置更改中幸存下来。”

I was asking why ViewModel is saving my old UI-related data after rotation...even though that's exactly what it's supposed to do...my mistake.我在问为什么 ViewModel 在旋转后保存我的旧 UI 相关数据......即使这正是它应该做的......我的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM