使用碎片清除栈

我将Android应用程序移植到了蜂窝中,为了使用碎片,我做了一个大的重构。 在我以前的版本中,当我按下主页button时,我用来执行ACTIVITY_CLEAR_TOP以重置回栈。

现在我的应用程序只是一个具有多个片段的Activity,所以当我按Homebutton时,只需要replace其中的一个片段即可。 我怎样才能清除我的背堆栈,而不必使用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(); } 

但同样可以使用类似的东西:

 FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE) 

这将popup所有状态到指定的一个。 然后你可以用你想要的来代替片段

要为@ Warpzit的评论作出回答,并使其他人更容易find…使用:

 fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 

充分尊重所有有关方面; 我很惊讶地看到有多less人可以用简单的方法清除整个碎片

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

根据Android文档 (关于name参数 – 声称的工作提议中的“null”)。

如果为null,则只popup顶部状态

现在,我意识到我缺乏对特定实现的了解(比如在给定的时间点有多less条logging),但是当我期待一个明确的定义更广泛的设备和供应商的行为:

(供参考,与此一起)

 FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();' int count = fm.getBackStackEntryCount(); for(int i = 0; i < count; ++i) { fm.popBackStack(); } 

接受的答案是不够的。 我不得不使用:

 FragmentManager fm = getSupportFragmentManager(); int count = fm.getBackStackEntryCount(); for(int i = 0; i < count; ++i) { fm.popBackStackImmediate(); } 

适用于我而不使用循环的简单方法:

  FragmentManager fragmentManager = getSupportFragmentManager(); //this will clear the back stack and displays no animation on the screen fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 

清除没有循环的backstack

 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) 

我只想补充一点:

使用以下从后台popup

fragmentManager.popBackStack()

只是从事务中删除碎片,没有办法从屏幕上删除碎片。 所以理想情况下,它可能不是可见的,但可能有两个或三个碎片堆叠在一起,在后面的按键,UI可能看起来杂乱,堆叠。

举一个简单的例子:

假设你有一个使用fragmentmanager.replace()加载Fragmnet B的fragmentA ,然后我们使用addToBackStack来保存这个事务。 所以stream程是:

第1步 – > FragmentA-> FragmentB(我们移到了FragmentB,但片段A在后台,不可见)。

现在你在fragmentB中做了一些工作,然后按下Savebutton – 保存后应该返回到fragmentA。

步骤2->保存FragmentB,我们回到FragmentA。

第3步 – >所以常见的错误是…在片段B中,我们将片段Manager.replace()fragmentB与片段A.

但实际发生的是,我们再次加载碎片A,replaceFragmentB。 所以现在有两个FragmentA(一个来自STEP-1,一个来自这个STEP-3)。

碎片A的两个实例堆叠在一起,可能不可见,但它在那里。

所以即使我们通过上述方法清除后台,事务也被清除,但不是实际的碎片。 因此,理想情况下,在保存button的按下时,只需简单地执行fm.popBackStack()fm.popBackImmediate()即可返回到fragmentA。

所以正确的Step3-> fm.popBackStack()返回已经在内存中的fragmentA。

只要使用这个方法,并把Context&Fragment标签传递给我们需要去除的后台碎片。

用法

 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(); } } 

我这样工作:

 public void showHome() { getHandler().post(new Runnable() { @Override public void run() { final FragmentManager fm = getSupportFragmentManager(); while (fm.getBackStackEntryCount() > 0) { fm.popBackStackImmediate(); } } }); } 

阅读文档并研究片段ID是什么,它似乎只是堆栈索引,所以这个工作:

 fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE); 

零( 0 )是堆栈的底部,所以popup它,包括清除堆栈。

CAVEAT:虽然上面的程序在我的程序中工作,但我有点犹豫,因为FragmentManager文档从来没有声明id是堆栈索引。 这是有道理的,而且我所有的debugging日志都是裸露出来的,但也许在某些特殊的情况下不会呢? 任何人都可以确认这种方式吗? 如果是这样,那么以上是最好的解决scheme。 如果不是,这是另一种方法:

 while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }