activity/fragment view的保存恢复

保存/恢复 activity和fragment

一、activity

当Activity的onSaveInstanceState被调用的时候,Activity将会从View 层次(View Hierachy)中的每一个View中自动搜集View的状态。请注意,只会搜集实现了View状态保存/恢复的内部方法的View的数据。一旦onRestoreInstanceState被调用,Activity将会将这些搜集到的数据一对一的返还给View 层次里在搜集的时候提供了同样的android:id属性的View。

这就是为什么尽管Activity已经被销毁,而我们并没有做一些特别的事情来保存状态,但是EditText中键入的文本仍然能够呈现的原因。这并不是什么魔法,这些View 的状态已经被自动的保存和恢复回来了。

这也是为什么View 在没有被设置android:id属性的时候不能保存和恢复自己的状态的原因。

尽管这些View 的状态被自动的保存了,但是Activity的成员变量并不会有同样的效果。这些成员变量会被和Activity一起销毁。你可以手动的保存和恢复它们,通过onSaveInstanceStateonRestoreInstanceState方法。

public class MainActivity extends AppCompatActivity {

    // These variable are destroyed along with Activity
    private int someVarA;
    private String someVarB;

    ...

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("someVarA", someVarA);
        outState.putString("someVarB", someVarB);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        someVarA = savedInstanceState.getInt("someVarA");
        someVarB = savedInstanceState.getString("someVarB");
    }

}

二、fragment

一旦Fragment从后退栈中返回,它的View 会被销毁,并重新创建。

这种情况下,Fragment并不会被销毁,只有Fragment中的View 会被销毁。 结果是,并不会发生任何实例状态的保存。但是上面展示的这些View在Fragment生命周期中被重新创建时,发生了什么?

别惊讶,因为Android是这样设计的。在这种情况下,Fragment中的View 状态的保存/恢复会被内部调用。结果就是,每一个实现了内部View 状态保存/恢复的View ,将会被自动的保存并且恢复状态,例如带有android:freezeText="true"属性的EditText或者TextView。就之前完美显示的一样。

请注意,在这种情况下,只有View 被销毁(并重建)了。Fragment仍然在这里,就像它内部的成员变量一样。所以你不需要对它们做任何事情。不需要任何额外的代码。

public class MainFragment extends Fragment {

    // These variable are destroyed along with Activity
    private int someVarA;
    private String someVarB;

    ...

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("someVarA", someVarA);
        outState.putString("someVarB", someVarB);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        someVarA = savedInstanceState.getInt("someVarA");
        someVarB = savedInstanceState.getString("someVarB");
    }

}

如果Fragment中的每一个View 都在内部实现了View 的状态的保存和恢复.在这种情况下,你就没有必要做任何事情,View 状态会被自动的恢复,并且Fragment中的成员变量也和之前的一样。

所以Fragment状态保存/恢复最佳实践的第一条件就是...

你应用中使用的每一个单独的View都必须在内部实现状态的保存和恢复

Android内部通过onSaveInstanceStateonRestoreInstanceState 方法提供了保存和恢复View 状态的机制。开发者的任务就是实现它。

基本上来说,每一个单独的Android提供的的标准View 组件都已经在内部完成了这些事情,例如EditText,TextView,Checkbox.
尽管也许你手动让它生效,例如,你需要为TextView设置android:freezeText为true,来使用这个功能。

但是如果我们讨论关于互联网上贡献的第三方的自定义组件。我必须说,它们大多数都没有实现这部分的代码,在使用中会导致很大的问题。

如果你决定使用第三方的自定义组件,你不得不确保它已经在内部实现了View 的保存和恢复,否则你必须创建继承这个三方组件的一个派生的子类,并且自己实现onSaveInstanceStateonRestoreInstanceState方法。

并且不要忘记为每一个你需要开启View状态保存和恢复的View设置android:id属性,不然它们的状态不能正确的恢复。

猜你喜欢

转载自blog.csdn.net/hpp_1225/article/details/83184877
今日推荐