使用碎片清除栈
我将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(); }