我的活动中有五个片段。在单击片段抽屉列表时,我正在调用setFrament()
方法。
它从活动中删除先前的片段,并根据要求添加新片段。
这是我的setFragment
方法代码。
protected void setFragment(final int position) {
// Remove currently active fragment
if (mActiveFragment != null) {
Fragment previous;
while ((previous = mFragmentManager
.findFragmentByTag(mActiveFragment.toString())) != null) {
mFragmentManager.beginTransaction().remove(previous).commit();
Log.e("in loop", "stuck");
}
}
// It's enum, generated according to position
FragmentType type = getFragmentType(position);
Fragment fragment = mFragmentManager.findFragmentByTag(type.toString());
if (fragment == null) {
fragment = createFragment(type);
}
mFragmentManager
.beginTransaction()
.replace(R.id.containerFrameLayout, fragment,
type.toString()).commit();
// Sets the current selected fragment checked in
// Drawer listview
mFragmentDrawerList.setItemChecked(position, true);
// set Actionbar title
getActionBar().setTitle(type + "");
mActiveFragment = type;
}
在这里,在更改片段的同时,它会永久地保持“卡住”状态,
我的问题是,
为什么remove(Fragment)
方法不会从活动中删除先前的片段?
答案 0 :(得分:2)
commit()
是一个异步调用,仅在Android系统重新获得控制权时执行。离开方法后,片段将不会被移除。
如果要删除先前的片段(假设只有一个片段),则可以将它们添加到backstack中。然后你可以调用popBackStack(null, 0)
,这将弹出后栈上的所有内容。虽然按下“后退”按钮也会弹出后备箱,如果用户要这样做的话。如果您不希望这种情况发生,您必须覆盖onBackPressed()
并自行处理。
编辑:
一种方法是跟踪所有ID或TAG,并单独调用remove
。
LinkedList<Integer> fragmentIds = new LinkedList<Integer>();
/*** Add fragment to FragmentManager ***/
fragmentIds.add(/** ID of fragment */);
/** Removing all fragments from FragmentManager **/
FragmentManager fm = getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
Fragment fragToRemove;
for(Integer id : fragmentIds)
{
fragToRemove = fm.findFragmentById(id);
transaction.remove(fragToRemove);
}
transaction.commit()
fragmentIds.clear();
但是,只要在同一容器上使用remove
方法,就不必在其中任何一个上调用replace()
。 replace()
将弹出上一个片段并添加新片段。只要事务没有被推送到backstack,前一个片段就会从Activity中分离并被丢弃。