分离未触发 onSaveInstanceState() 的 Fragment

Detaching a Fragment not triggering onSaveInstanceState()

提问人:Dan 提问时间:8/28/2012 更新时间:8/28/2012 访问量:9275

问:

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

问题是,从来没有被调用过。调用 's 和 方法,但提供的 to 保持为 null。onSaveInstanceStateFragmentonDestroyViewonCreateViewBundleonCreateView

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

片段:

@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);
    }
}
Android 保存 片段 分离

评论

0赞 DeeV 8/28/2012
stackoverflow.com/questions/8503629/ 的可能副本...

答:

8赞 zapl 8/28/2012 #1

Fragment#onSaveInstanceState仅当主机被销毁时才调用,并且您有可能返回到相同的活动,并且片段仍被添加到 .最常见的情况是屏幕旋转。ActivityFragmentFragmentManager

例如,我认为您还需要执行setRetainInstance(true)。不过不太确定这一点。FragmentonCreate

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

如果你只是碎片,你需要做的就是把它拿回来。detach()FragmentManager

您应该查看两个示例:

ActionBar FragmentTabs 和 TabHost FragmentTabs

该示例使用TabHost

ft.add(containerId, fragment, tag);
// later
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);

要查找以前添加的 S 的实例,请一直工作到您Fragmentremove()Fragment


关于 / :一旦片段分离,就会调用它,因为下次附加它时需要创建一个新的 .请注意,当您 fragment 时不会调用它,因为它仍然附加到 .它仅与视图层次结构分离。onCreateViewonDestroyViewViewFragment#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;
}

评论

0赞 Dan 8/28/2012
感谢您的回复。我的印象是,使用 setRetainInstance(true) 会占用大量内存,因为这意味着存储选项卡而不是销毁和重新创建它们,但我会试一试。我是否必须通过 FragmentManager 获取我的 Fragment,或者我可以在字段中保留对它们的引用?
0赞 zapl 8/28/2012
您根本不需要参考。FragmentManager 有对它们的引用,但如果您不添加内存泄漏,则可以添加一个。记忆强度取决于您在片段中使用的量,如果您做对了,内存强度可能接近 0
0赞 Dan 8/28/2012
我想我现在已经在你的第一个例子的帮助下解决了这个问题。我的问题是,我在 Fragment 的 onActivityCreated() 方法中有一些代码,它本质上是重置它,因为我没有意识到这个方法会多次运行。
0赞 zapl 8/28/2012
是的,活动会在配置更改(如轮换)时重新创建,并且您会再次被调用。获得正确的生命周期是很棘手的:/ 将是一个只应该被调用一次的地方。OnCreate