6

我的 Android 应用程序有一个ActionBar变化,它Fragment占据了一定的FrameLayout. 我正在尝试onSaveInstanceState在选项卡更改时保存 Fragment 的状态,以便可以在onCreateView.

问题是,onSaveInstanceState永远不会被调用。' FragmentsonDestroyViewonCreateView方法被调用,但Bundle提供的 toonCreateView保持为空。

有人可以向我解释何时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
}

活动:

/**
 * 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);
    }
}
4

1 回答 1

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);

要查找先前添加的 s的实例Fragment,直到您remove()Fragment


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


还有另一个很好的例子,关于如何在 Android Training - Caching Bitmaps中保留片段状态/如何使用片段保留状态。

但是,该示例缺少关键行:

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;
}
于 2012-08-27T18:05:26.310 回答