Fragments 中的“onViewStateRestored”如何工作?

Posted

技术标签:

【中文标题】Fragments 中的“onViewStateRestored”如何工作?【英文标题】:How does `onViewStateRestored` from Fragments work? 【发布时间】:2013-07-21 10:58:01 【问题描述】:

我真的对片段的内部状态感到困惑。 我有一个 Activity 一次只保存一个 Fragment 并替换它,如果应该显示另一个 Fragment。从文档中,onSaveInstanceState 仅在调用 onSaveInstanceState 的活动时才被调用(在我的情况下没有调用)。

如果我停止我的 Fragment,我会自己将其状态存储在 Singleton 中(是的,我知道我也讨厌 Singleton,但我不打算这样做)。 所以我必须重新创建整个ViewHirarchy,创建新视图(通过使用关键字new),恢复其状态并在onCreateView 中返回它们。 我在这个视图中也有一个复选框,我明确地想要存储它的状态。

但是,FragmentManager 想要“智能”并使用我从未自己创建的 Bundle 调用 onViewStateRestored,并“恢复”旧 CheckBox 的状态并将其应用于我的新复选框。这引发了很多问题:

我可以从onViewStateRestored 控制捆绑包吗?

FragmentManager 如何获取(可能是垃圾收集的)CheckBox 的状态并将其应用于新的 CheckBox?

为什么只保存 Checkbox 的状态(Not of TextViews??)

总结一下:onViewStateRestored 是如何工作的?

注意我使用的是 Fragmentv4,所以onViewStateRestored 不需要 API > 17

【问题讨论】:

【参考方案1】:

嗯,有时片段会让人有点困惑,但过一段时间你就会习惯它们,并知道它们毕竟是你的朋友。

如果在片段的 onCreate() 方法上,您可以: setRetainInstance(true);您的视图的可见状态将被保留,否则不会。

假设有一个 F 类的名为“f”的片段,它的生命周期是这样的: - 在实例化/附加/显示时,这些是 f 的方法,按以下顺序调用:

F.newInstance();
F();
F.onCreate();
F.onCreateView();
F.onViewStateRestored;
F.onResume();

此时,您的片段将在屏幕上可见。 假设设备是旋转的,因此必须保留片段信息,这就是旋转触发的事件流:

F.onSaveInstanceState(); //save your info, before the fragment is destroyed, HERE YOU CAN CONTROL THE SAVED BUNDLE, CHECK EXAMPLE BELLOW.
F.onDestroyView(); //destroy any extra allocations your have made
//here starts f's restore process
F.onCreateView(); //f's view will be recreated
F.onViewStateRestored(); //load your info and restore the state of f's view
F.onResume(); //this method is called when your fragment is restoring its focus, sometimes you will need to insert some code here.


//store the information using the correct types, according to your variables.
@Override
public void onSaveInstanceState(Bundle outState) 
    super.onSaveInstanceState(outState);
    outState.putSerializable("foo", this.foo);
    outState.putBoolean("bar", true);


@Override
public void onViewStateRestored(Bundle inState) 
    super.onViewStateRestored(inState);
    if(inState!=null) 
        if (inState.getBoolean("bar", false)) 
            this.foo = (ArrayList<HashMap<String, Double>>) inState.getSerializable("foo");
        
    


【讨论】:

您的回答似乎暗示 F()F.onCreate() 在配置更改(例如屏幕方向更改)时不会被调用。这不是真的。两者都确实被调用了。 还请注意,onSaveInstanceState 实际上是在片段进入后台后立即调用的。在onSaveInstanceState 之后,onDestroy 并不总是需要被调用。

以上是关于Fragments 中的“onViewStateRestored”如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

React开发(214):React中的Fragments

React开发(215):React中的Fragments的动机

使用 Fragments 为 Android 中的每个选项卡单独返回堆栈

响应Activity中的ViewPager2 Fragments事件

如何在 Fragments 中实现 onBackPressed()?

是 Android Fragments View 还是 ViewGroup