首页 文章

来自Fragments的`onViewStateRestored`如何工作?

提问于
浏览
17

我真的很困惑片段的内部状态 . 如果另一个Fragment应该显示,我有一个Activity只能同时保存一个Fragment并替换它 . 从文档 onSaveInstanceState 仅在调用活动 onSaveInstanceState 时被调用(在我的情况下不调用) .

如果我停止我的碎片,我的想法是这样做的 . 所以我必须重新创建整个 ViewHirarchy ,创建新视图(通过使用关键字 new ),恢复其状态并在 onCreateView 中返回它们 . 我在这个View中也有一个Checkbox,我明确地不想存储它的状态 .

但是 FragmentManager 想要"intelligent"并且用我从未创建过的Bundle调用 onViewStateRestored ,并且"restores"旧 CheckBox 的状态并将其应用于我的新CheckBox . 这引发了很多问题:

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

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

为什么它只保存Checkbox的状态(不是TextViews ??)

总而言之: onViewStateRestored 如何运作?

注意我正在使用Fragmentv4,因此 onViewStateRestored 不需要API> 17

1 回答

  • 21

    好吧,有时片段会让人感到有些困惑,但过了一段时间你就会习惯它们,并且知道它们毕竟是你的朋友 .

    如果在片段的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");
            }
        }
    
    }
    

相关问题