【问题标题】:Detaching a Fragment not triggering onSaveInstanceState()分离不触发 onSaveInstanceState() 的片段
【发布时间】:2012-08-27 17:41:31
【问题描述】:

我的 Android 应用程序有一个 ActionBar,它改变了 Fragment 占用某个 FrameLayout。我正在尝试使用onSaveInstanceState 来保存一个Fragment 在tab 改变时的状态,以便可以在onCreateView 中恢复。

问题是,onSaveInstanceState 永远不会被调用。调用了FragmentonDestroyViewonCreateView 方法,但提供给onCreateViewBundle 仍然为空。

有人可以向我解释什么时候实际调用了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);
    }
}

【问题讨论】:

标签: android save fragment detach


【解决方案1】:

Fragment#onSaveInstanceState 仅在托管 FragmentActivity 被销毁并且您有可能返回相同的活动并且片段仍添加到 FragmentManager 时才被调用。最常见的情况是屏幕旋转。

我认为您的Fragment 也需要在onCreate 中执行setRetainInstance(true)。不过不太确定这一点。

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

如果您只是detach() 片段,您只需向FragmentManager 索取即可。

你应该看看两个例子:

ActionBar FragmentTabsTabHost FragmentTabs

TabHost 示例使用

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

要查找以前添加的Fragments 的实例,直到您remove()Fragment 为止


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


还有另一个很好的例子,关于如何在 Android 培训中保留片段状态/如何使用片段来保留状态 - 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;
}

【讨论】:

  • 感谢您的回复。我的印象是使用 setRetainInstance(true) 会占用大量内存,因为这意味着存储选项卡而不是销毁和重新创建它们,但我会试一试。我必须通过 FragmentManager 获取我的 Fragment 还是可以在字段中保留对它们的引用?
  • 您根本不需要参考。 FragmentManager 对它们有引用,但如果您不添加内存泄漏,则可以添加一个。记忆强度取决于你在片段中使用了多少,如果你做得对,它可能接近于 0
  • 我想在您的第一个示例的帮助下,我现在已经对此进行了排序。我的问题实际上是我在 Fragment 的 onActivityCreated() 方法中有一些代码,它实际上是在重置它,因为我没有意识到这个方法会运行不止一次。
  • 是的,活动会在配置更改(如轮换)时重新创建,您会再次被调用。获得正确的生命周期是很棘手的:/OnCreate 将是一个只应该被调用一次的地方。
猜你喜欢
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多