分离片段不会触发onSaveInstanceState()

Dan*_*Dan 6 android save detach fragment

我的Android应用程序有一个ActionBar变化,Fragment占用了一定的FrameLayout.当我onSaveInstanceState更改选项卡时,我试图用来保存片段的状态,以便可以恢复它onCreateView.

问题是,onSaveInstanceState永远不会被称为.在FragmentonDestroyViewonCreateView方法的调用,但Bundle供给onCreateView仍然是零.

有人可以向我解释onSaveInstanceState实际调用的时间,如何确保在切换选项卡时调用它,或者在Fragment分离和重新连接时保存和恢复状态的最佳实践?

分段:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.event_log, container, false);

    // Retrieve saved state
    if (savedInstanceState != null){
        System.out.println("log retrieved");
    } else {
        System.out.println("log null");
    }

    return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    System.out.println("log saved");
    super.onSaveInstanceState(outState);
    // more code
}
Run Code Online (Sandbox Code Playgroud)

活动:

/**
 * Detach the current Fragment, because another one is being attached.
 */
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    if (tab.getText().equals(getString(R.string.tab_events))){
        if (frEventLog != null) {
            ft.detach(frEventLog);
    }
}
Run Code Online (Sandbox Code Playgroud)

zap*_*apl 8

Fragment#onSaveInstanceState只有在Activity托管Fragment被销毁时才会被调用,并且有可能你可以回到相同的活动并且片段仍然被添加到FragmentManager.最常见的情况是屏幕旋转.

我想你Fragment也将需要做setRetainInstance(true)onCreate,例如.虽然不太确定这一点.

例如,当您按下主页按钮时,您还应该看到调用此方法.这将破坏活动,但您可以通过使用任务列表返回到它.

如果你只detach()需要片段,那么你需要做的就是要求FragmentManager它.

您应该看一下两个例子:

ActionBarFragmentTabsTabHostFragmentTabs

TabHost示例使用

ft.add(containerId, fragment, tag);
// later
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);
Run Code Online (Sandbox Code Playgroud)

找到先前添加的情况下FragmentS,一直工作到你remove()一个Fragment


关于onCreateView/ onDestroyView:一旦片段被分离,就会调用它,因为下次附加它时需要创建一个新片段View.请注意,片段Fragment#onDetached()时不会调用detach()它,因为它仍然附加到片段Activity.它仅与视图层次结构分离.


关于如何在Android培训 - 缓存位图中保留片段状态/如何使用片段来保留状态,还有另一个很好的例子.

这个例子缺少一条关键线:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
    if (fragment == null) {
        fragment = new RetainFragment();
        fm.beginTransaction().add(fragment, TAG).commit(); // << add this
    }
    return fragment;
}
Run Code Online (Sandbox Code Playgroud)