当序列中的所有片段都添加到backstack中时,Popbackstack工作正常,但是当其中一个事务没有添加到backstack中时,它不起作用。
这是我的导航:
1.更换片段以加载主片段。此事务未添加到backstack。
替换片段以加载登录片段。此事务已添加到backstack。
3.更换片段以加载登录片段。此事务不会添加到backstack。
现在,当我没有任何反应时按下按钮。理想情况下,它应该从登录片段转到主片段。 这是我在主要活动中的onbackpressed方法:
@Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount()>0)
{
FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1);
String str = backStackEntry.getName();
FragmentManager fm=getSupportFragmentManager();
//getSupportFragmentManager().popBackStackImmediate();
fm.popBackStack(str, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
else {
super.onBackPressed();
}
}
答案 0 :(得分:1)
popBackstack
只有'pop'在backstack中。
由于在按下时按LoggedInFragment替换LoginFragment时没有添加事务:
但是因为在HomeFragment之后添加了LoggedInFragment,HomeFragment会显示在它下面。因此,您无法将其视为LoggedInFragment隐藏。
一种解决方案是在LoggedInFragment替换LogInFragment时将事务添加到后台堆栈。
然后在onBackPressed
中测试当前片段是否为LoggedInFragment。如果是这种情况,则将后向堆栈弹出到HomeFragment(不包括在内)。就像那样,LoggedInFragment和LogInFragment都会弹出。
修改强>
@Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentById(R.id.my_fragment_container);
// If there is something in the back stack AND the current fragment is the LoggedInFragment
if (manager.getBackStackEntryCount() > 0
&& fragment instanceof LoggedInFragment) {
manager.popBackStack(HomeFragment.class.getSimpleName(), 0);
} else {
super.onBackPressed();
}
}
为了按名称检索HomeFragment,您需要在HomeFragment替换当前片段时标记您的事务。通常我用片段的类简单名称标记所有事务,以便我可以重试任何片段:
transaction.replace(R.id.my_fragment_container, fragment, fragment.getClass().getSimpleName());
答案 1 :(得分:0)
Eselfar对问题的解释是正确的,但他提供的代码对我来说不够通用。
我(希望)通过以下代码在一般情况下解决了这个问题:
@Override
public void onBackPressed() {
Fragment currentFragment = getCurrentFragment();
if (mFragmentManager.getBackStackEntryCount() > 0) {
// In a normal world, just popping back stack would be sufficient, but since android
// is not normal, a call to popBackStack can leave the popped fragment on screen.
// Therefore, we start with manual removal of the current fragment.
removeCurrentFragment();
mFragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
private Fragment getCurrentFragment() {
return mFragmentManager.findFragmentById(getContentFrameId());
}
private void removeCurrentFragment() {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.remove(getCurrentFragment());
ft.commit();
// not sure it is needed; will keep it as a reminder to myself if there will be problems
// mFragmentManager.executePendingTransactions();
}