在两个片段之间切换的最佳方式

时间:2013-09-25 19:08:48

标签: android android-fragments

我对在单个活动之间切换两个片段的最佳方法感兴趣。

我已经阅读了15篇Stack Overflow帖子和5篇关于如何做到这一点的博客帖子,虽然我认为我拼凑了一个解决方案,但我不相信它是最好的。因此,我希望听到人们对正确处理此问题的看法,特别是关于父活动和片段的生命周期。

以下是详细情况:

  1. 可显示两个可能片段之一的父活动。
  2. 这两个片段的状态是我希望在会话中持续存在,但不一定需要在会话之间保留。
  3. 许多其他活动,例如父活动和碎片可能被埋没在后堆栈中并因内存不足而被破坏。
  4. 我希望能够使用后退按钮在片段之间移动(据我所知,我不能使用setRetainInstance)。
  5. 除了一般的架构建议,我还有以下未解决的问题:

    1. 如果由于内存不足而导致父活动被破坏,我如何保证两个片段的状态将保留,如以下帖子所示:When a Fragment is replaced and put in the back stack (or removed) does it stay in memory?。我只需要指向父活动中每个片段的指针吗?
    2. 父活动跟踪当前显示的片段的最佳方式是什么?
    3. 提前致谢!

2 个答案:

答案 0 :(得分:7)

我最后使用支持片段管理器添加了两个片段,然后使用detach / attach在它们之间切换。我能够使用commitAllowingStateLoss()因为我在其他地方保留了视图的状态,并在onResume()中手动设置了正确的片段。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    

    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.my_layout, new AFragment(), TAG_A);
    fragmentTransaction.add(R.id.my_layout, new BFragment(), TAG_B);
    fragmentTransaction.commit();
}

public void onResume() {
    super.onResume();
    if (this.shouldShowA) {
        switchToA();
    } else {
        switchToB();
    }
}

private void switchToA() {
    AFragment fragA = (AFragment) getSupportFragmentManager().findFragmentByTag(TAG_A);
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.detach(getSupportFragmentManager().findFragmentByTag(TAG_B));
    fragmentTransaction.attach(fragA);
    fragmentTransaction.addToBackStack(null);

    fragmentTransaction.commitAllowingStateLoss();
    getSupportFragmentManager().executePendingTransactions();
}

答案 1 :(得分:2)

您可能需要考虑在父Activity中使用ViewPager,以便在片段之间切换。

所以你可以滑过它们。

如果你想在会话期间保持他们的状态,即使父活动被销毁,你需要使它们Parcelable,这样你就可以保存状态,即使那个时候没有实例化类。如果您旋转设备并希望将当前情况/数据保留在屏幕上,则还需要执行此操作。

您应该在Parcelable方法中将它们写入onPause,然后在onResume个方法中重新创建它们。这样,由于设备方向的改变,它们是否被销毁或必须重新创建并不重要。

如果您希望能够使用Backbutton在这些片段之间切换,您可以抓住按钮点击onBackPressed并相应地处理它。

如果你需要弄清楚你在特定时间显示的片段是什么,你问ViewPager那时他正在展示什么片段,所以你不必跟踪,你可以问一个谁知道,如果你需要知道它。