ACTIVITY_CLEAR_TOP
以重置后退堆栈。
现在我的应用程序只是一个包含多个片段的单一活动,因此当我按下Home键时,我只需替换其中一个片段。如何在不使用带有ACTIVITY_CLEAR_TOP
标志的startActivity
的情况下清除我的后退堆栈?ACTIVITY_CLEAR_TOP
以重置后退堆栈。
现在我的应用程序只是一个包含多个片段的单一活动,因此当我按下Home键时,我只需替换其中一个片段。如何在不使用带有ACTIVITY_CLEAR_TOP
标志的startActivity
的情况下清除我的后退堆栈?根据Joachim的回答,Dianne Hackborn提出:
http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42
我最终只使用了如下代码:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
但也可以使用类似下面这样的东西:
((AppCompatActivity)getContext()).getSupportFragmentManager().popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
这会将所有直到指定状态的状态都弹出。然后,您只需用所需内容替换片段即可。
为了回复@Warpzit的评论并让其他人更容易找到,以下是建议:
使用:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
A
到 B
再到 C
并在 C
上调用此方法返回到 A
时,这只能工作一次。当我再次从 A
经由 B
到 C
并触发 fragmentManager.popBackStackImmediate
时,它不会再次导航到 A
。我使用 getParentFragmentManager().beginTransaction().replace(x, y).addToBackStack(null).commit();
从 A
到 B
,从 B
到 C
进行导航。有什么想法如何解决我的问题吗? - CodeNinja对于所有相关方的尊重,我很惊讶看到你们中有多少人可以通过简单地使用 fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
清除整个片段回退栈。
根据Android文档(关于“name”参数 - 在所声称的工作方案中的“null”):
如果为null,则只会弹出顶部状态。
现在,我确实意识到我缺乏你们特定实现方面的知识(例如,在给定时间点上你们在返回栈中有多少条目),但是当期望在更广泛的设备和供应商范围内获得良好定义的行为时,我会押下所有的钱支持被接受的答案:
(供参考,类似于这样的东西)
FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
fm.popBackStack();
}
清除回退栈而不循环
String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);
其中name是addToBackStack()方法的参数
getSupportFragmentManager().beginTransaction().
.replace(R.id.container, fragments.get(titleCode))
.addToBackStack(name)
适合我并且不使用循环的简单方法:
FragmentManager fragmentManager = getSupportFragmentManager();
//this will clear the back stack and displays no animation on the screen
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
接受的答案对我来说不够,我必须使用:
FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
fm.popBackStackImmediate();
}
popBackStackImmediate()
同步执行事务,一般来说不推荐使用。 - Damien Diehl嗨~我发现了一种更好的解决方案,来源于:https://gist.github.com/ikew0ng/8297033
/**
* Remove all entries from the backStack of this fragmentManager.
*
* @param fragmentManager the fragmentManager to clear.
*/
private void clearBackStack(FragmentManager fragmentManager) {
if (fragmentManager.getBackStackEntryCount() > 0) {
FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(0);
fragmentManager.popBackStack(entry.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
我想要补充一点:
使用以下方法从后退栈中弹出:
fragmentManager.popBackStack()
只是将片段从事务中移除,绝不会将其从屏幕中删除。 因此,理论上,它可能对您不可见,但可能有两个或三个片段在彼此之上堆叠,在按返回键时,UI 可能看起来混乱、重叠。
举个简单的例子:
假设您有一个 FragmentA,使用 fragmentmanager.replace() 加载 Fragmnet B,然后我们执行 addToBackStack,以保存此事务。 所以流程是:--
步骤1 -> FragmentA->FragmentB(我们转到 FragmentB,但 FragmentA 在后台,不可见)。
现在,您在 fragmentB 中进行了一些工作,并按下“保存”按钮,此后应返回 fragmentA。
步骤2-> 在保存 FragmentB 后,我们回到 FragmentA。
步骤3-> 因此,常见的错误是... 在 FragmentB 中,我们将 fragment Manager.replace() 的 fragmentB 替换为 fragmentA。
但实际上正在发生什么,我们再次加载 FragmentA,将 FragmentB 替换掉。现在有两个 FragmentA(一个来自 STEP-1,另一个来自 STEP-3)。
两个 FragmentA 实例被堆叠在彼此之上,可能是不可见的,但它确实存在。
因此,即使我们通过上述方法清除了后退栈,事务已经清除,但实际的片段并没有被清除。 因此,在这种特殊情况下,按保存按钮时,您只需通过 fm.popBackStack() 或 fm.popBackImmediate() 返回到已经在内存中的 fragmentA 即可。
因此,正确的第三步-> fm.popBackStack() 返回到已经在内存中的 fragmentA。
针对 Kotlin 开发者:
repeat(supportFragmentManager.backStackEntryCount) {
supportFragmentManager.popBackStack()
}
clearFragmentByTag(context, FragmentName.class.getName());
public static void clearFragmentByTag(Context context, String tag) {
try {
FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();
for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
String backEntry = fm.getBackStackEntryAt(i).getName();
if (backEntry.equals(tag)) {
break;
} else {
fm.popBackStack();
}
}
} catch (Exception e) {
System.out.print("!====Popbackstack error : " + e);
e.printStackTrace();
}
}