我有一个关于从后台栈中删除特定片段的问题。我的场景如下:将Fragment-1替换为Fragment-2,然后将Fragment-2替换为Fragment-3。
调用顺序; Fragment-1 -> Fragment-2 -> Fragment-3。
当Fragment-3在屏幕上时,然后点击返回按钮,我想回到Fragment-1。这意味着我想从后台栈中删除Fragment-2。
如何做到这一点?
我有一个关于从后台栈中删除特定片段的问题。我的场景如下:将Fragment-1替换为Fragment-2,然后将Fragment-2替换为Fragment-3。
调用顺序; Fragment-1 -> Fragment-2 -> Fragment-3。
当Fragment-3在屏幕上时,然后点击返回按钮,我想回到Fragment-1。这意味着我想从后台栈中删除Fragment-2。
如何做到这一点?
回退栈中不包含Fragment
,而是FragmentTransaction
。当你调用popBackStack()
时,事务会被再次应用,但是是后向的。这意味着(假设每次都addToBackStackTrace(null)
),在你的回退栈中有:
1->2
2->3
如果你不将第二个事务添加到后退栈中,结果就是你的后退栈只有
1->2
因此,按下返回按钮将导致执行2->1
,由于片段2不存在(您现在在片段3上),因此会导致错误。
最简单的解决方案是在从2到3之前弹出后退栈
//from fragment-2:
getFragmentManager().popBackStack();
getFragmentManager().beginTransaction()
.replace(R.id.container, fragment3)
.addToBackStack(null)
.commit();
我在这里做的是这样的:从片段2返回到片段1,然后直接进入片段3。这样按下返回按钮将再次从3返回到1。
我有一个和你很类似的情况,我的解决方案是检查我拥有的backStack事务数量。如果事务数量大于0,那么我会立即弹出它,这样在按返回键时就会跳过它。
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
...
fragmentTransaction.replace(R.id.main_fragment, newFrag, MAIN_FRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
这将成功执行:
A -> B(按下返回键)-> 返回到 A
A -> B -> C(按下返回键)-> 返回到 A
我唯一看到的不足之处是在进入片段C之前,会有一个快速的闪烁,显示了片段A。
.popStack()
- 在我的情况下 - 导致视图在回到A之后自动恢复到C - 在按返回按钮之前。这里列出的popBackStackImmediate()
是我情况下的关键所在,现在我可以从C返回到A的返回按钮了 - 我遇到的其他答案都没有提到它。谢谢! - Gene Bo如果您在同一个活动中添加/启动了所有三个片段,而不是使用add()
,请改用replace()
(将Fragment2
替换为Fragment3
)。replace
方法会在添加新的片段之前从后退栈中删除当前片段。如果您要从另一个活动启动Fragment3
,因此无法使用replace()
,请在启动新活动之前从后退栈中删除Fragment2
(这将添加Fragment3
):
// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.remove(this) // "this" refers to current instance of Fragment2
.commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity,
// start that activity instead
fragmentManager.beginTransaction()
.add(R.id.a_container_view_in_activity, new Fragment3(),
Fargment3.FRAGMENT3_ID)
.commit();
代码片段A -> 片段B:
将片段A添加到片段回退栈中
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentB());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
代码片段 B -> 代码片段 C:
不要将 代码片段 B 添加到碎片的后退栈中。
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentC());
fragmentTransaction.commit();
希望这能对您有所帮助。
for (int i = 0; i < mFragmentManager.getBackStackEntryCount(); i++) {
currentFragment = mFragmentManager.getFragments().get(i);
if (!(currentFragment instanceof ParticularFragment))
mFragmentManager.popBackStack();
else
break;
}