我的android平板电脑应用程序的布局包括一个项目列表和一个详细信息视图。选择列表项时,关联的内容将显示在“详细信息”视图中。

+--------+-------------+
| Item 1 |             |
+--------+    Item     |
| Item 2 |   details   |
+--------+             |
| Item 3 |             |
+--------+-------------+

details视图是一个Fragment视图,它以编程方式膨胀为一个FrameLayout占位符:
<FrameLayout
    android:id="@+id/detail_fragment_placeholder"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

以下是Fragment操作:
getSupportFragmentManager()
    .beginTransaction()
    .replace(containerViewId, fragment, fragmentTag)
    .addToBackStack(backStackStateName)
    .commit();

当用户依次选择一个项目时,[Dx]的多个实例将添加到backbackback中。
                [D3]
        [D2]    [D2]
[D1] -> [D1] -> [D1]

因此,用户需要多次按下back按钮,从backbackback中弹出实例以清空details视图。
当现有DetailsFragment[Dx]与新DetailsFragmentfragmentTag匹配时,如何替换backbackback上的现有fragment实例?
[D1] -> [D2] -> [D3]

最佳答案

我不确定我是否正确地理解了你的问题。如果您想用来自backbackback顶部的某个标记替换多个片段,用一个具有相同标记的片段,那么您可以使用以下方法。
不要使用标记来识别片段,而是为不同类型的片段设置不同的backback名称。您仍然可以使用片段标记,但它无助于解决此特定问题。然后逐个手动从backbackback中移除片段,直到顶部有一个具有不同backbackback名称的片段或没有剩余的片段。

  public void addFragment(final int containerViewId, final Fragment fragment,
      final String backStackName, final boolean replace) {
    final FragmentManager fragmentManager = getSupportFragmentManager();

    if (replace) {
      while (fragmentManager.getBackStackEntryCount() > 0) {
        final int last = fragmentManager.getBackStackEntryCount() - 1;
        final FragmentManager.BackStackEntry entry =
            fragmentManager.getBackStackEntryAt(last);
        if (!TextUtils.equals(entry.getName(), backStackName)) {
          break;
        }

        fragmentManager.popBackStackImmediate();
      }
    }

    fragmentManager
        .beginTransaction()
        .replace(containerViewId, fragment)
        .addToBackStack(backStackName)
        .commit();
    fragmentManager.executePendingTransactions();
  }

现在,如果您进行以下调用,您的backbackback将只包含fragment1fragment4
addFragment(R.id.container, fragment1, "D2", false);
addFragment(R.id.container, fragment2, "D1", false);
addFragment(R.id.container, fragment3, "D1", false);
addFragment(R.id.container, fragment4, "D1", true);

更新:
在这种情况下,以下代码就足够了:
getSupportFragmentManager().popBackStack(
    backStackStateName, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager()
    .beginTransaction()
    .replace(containerViewId, fragment, fragmentTag)
    .addToBackStack(backStackStateName)
    .commit();

https://github.com/tuxmobil/CampFahrplan/pull/148

08-27 16:18