如何在背板上压碎与其碎片标签相匹配的碎片?

JJD*_*JJD 5 android android-fragments back-stack fragmentmanager

我的Android平板电脑应用的布局包括项目列表和详细信息视图.选择列表项时,关联的内容将显示在详细信息视图中.

+--------+-------------+ 
| Item 1 |             |
+--------+    Item     |
| Item 2 |   details   |
+--------+             |
| Item 3 |             |
+--------+-------------+
Run Code Online (Sandbox Code Playgroud)

详细信息视图是以Fragment编程方式膨胀到FrameLayout占位符中的:

<FrameLayout
    android:id="@+id/detail_fragment_placeholder"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
Run Code Online (Sandbox Code Playgroud)

这是Fragment操作:

getSupportFragmentManager()
    .beginTransaction()
    .replace(containerViewId, fragment, fragmentTag)
    .addToBackStack(backStackStateName)
    .commit();
Run Code Online (Sandbox Code Playgroud)

多个实例[Dx]DetailsFragment,当用户相继选择一个项目被添加到堆栈中.

                [D3]
        [D2]    [D2]
[D1] -> [D1] -> [D1]
Run Code Online (Sandbox Code Playgroud)

因此,用户需要多次按BACK按钮从后台弹出实例以清空详细信息视图.

我怎么能取代现有的实例[Dx]DetailsFragment对返回堆栈时,fragmentTag现有的fragment相匹配的fragmentTag新的fragment

[D1] -> [D2] -> [D3]
Run Code Online (Sandbox Code Playgroud)

Mic*_*ael 1

我不确定我是否正确理解你的问题。如果您想用具有相同标签的单个片段替换来自后台堆栈顶部的带有某个标签的多个片段,那么您可以使用以下方法。

不使用标签来标识片段,而是为不同类型的片段设置不同的返回堆栈名称。您仍然可以使用片段标签,但它无助于解决这个特定问题。然后手动从backstack中一一删除fragment,直到顶部有一个具有不同backstack名称的fragment或者没有剩余的fragment。

  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();
  }
Run Code Online (Sandbox Code Playgroud)

现在,如果您进行以下调用,您的后台堆栈将仅包含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);
Run Code Online (Sandbox Code Playgroud)

更新

在这种特殊情况下,以下代码就足够了:

getSupportFragmentManager().popBackStack(
    backStackStateName, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager()
    .beginTransaction()
    .replace(containerViewId, fragment, fragmentTag)
    .addToBackStack(backStackStateName)
    .commit();
Run Code Online (Sandbox Code Playgroud)

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