从Android后退栈中删除一个特定的片段

21

我在Android平板应用中使用了2个片段。一个位于屏幕左侧,另一个位于右侧。当您在右边的片段上单击按钮时,另一个片段将添加到右侧片段的顶部。此片段被添加到后退堆栈中。

FragmentTransaction ft = getFragmentManager().beginTransaction(); 
ft.add(R.id.fragmentlayout, fragment2);
ft.addToBackStack("Fragment2");
ft.commit();

返回栈现在是:

[片段1] -> [片段2]

左侧还有一个按钮,可以打开与Fragment 2相同的Fragment并将其添加到返回栈中。返回栈现在是:

[片段1] -> [片段2] -> [片段3]

在Fragment 2上有一个关闭该Fragment的按钮。

getFragmentManager().popBackStack("Fragment2", FragmentManager.POP_BACK_STACK_INCLUSIVE);

问题在于当我仅想关闭 [片段 2] 时,[片段 3] 也会被销毁。我可以通过调用下面的代码手动删除片段。

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment2).commit();

但是回退栈将会保留

[片段1] -> [(幽灵)片段2] -> [片段3]

因此,您需要再按一次返回按钮才能关闭应用程序。

有没有办法仅从回退栈中移除[片段2]并在屏幕上保留[片段3]?


4
据我所知,这是不可能的。这就是为什么它被称为"堆栈"的原因。 - Vladimir Mironov
你需要通过用空片段替换它来删除先前的片段,只有这样才能离开Fragment 3。 - GrIsHu
4个回答

5

你可以简单地创建自己的返回栈并覆盖 onBackPressed() 方法,以任何你认为合适的方式进行处理。我认为没有其他方法可以实现所需的行为。

你自己的返回栈可以简单地是一个用于存储片段标签的 ArrayList


2
我刚回答过一个类似的问题,所以这里是那个回答的链接
该实现允许您从后退栈的任何位置移除Fragment,并且这是通过使用反射修改FragmentManagerImplBackStackRecord中存储后退栈信息的内部变量来实现的。
虽然我不鼓励使用它,但我希望它能有所帮助。

0

这个解决方案只适用于您的情况。 您不需要将Fragment2放入后退栈中。您可以删除代码“ft.addToBackStack(“Fragment2”)”。 Fragment2不在堆栈中。因此,您可以关闭Fragment2,并将[fragment 3]留在屏幕上。


0
你可以创建自己的片段管理器/观察者。它只是一个简单的列表或映射。使用标签或类名(getClass)跟踪它们。这样,您将能够避免创建新片段并重用缓存的片段,从而控制内存消耗。
您还将能够按照自己的方式操作片段(覆盖onBackPressed并推送任何喜欢的片段),而不仅仅是使用Google建议/可以完成的方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接