片段addToBackStack()和popBackStackImmediate()不起作用

我目前正在构建Android应用程序(14 <= SDK <= 21),使用一个ActionBarActivity和更多Fragments ,例如ListFragmentMapFragment ,它们在单个FrameLayout视图中交换。

ActionBarActivity自动替换/提交片段A.然后,当用户点击一个按钮时,托管活动替换/提交一个新的不同片段B.我的目标是让用户在按下后退按钮时返回片段A 。

现在有些代码了。

主要活动

 public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener, StopItemFragment.OnFragmentInteractionListener { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fragmentManager = getFragmentManager(); fragmentManager.enableDebugLogging(true); ... if (fragmentManager.findFragmentById(R.id.content_frame) == null) { StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment fragmentManager.beginTransaction() .replace(R.id.content_frame, list) .addToBackStack(null) .commit(); } ... @Override public void onFragmentInteraction(String id) { selectItem(Integer.parseInt(id)); } private void selectItem(int position) { StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment ... fragmentManager.beginTransaction() .replace(R.id.content_frame, fragment) .commit(); ... } } 

问题

即使调用addToBackStack() ,当我在片段B上时,我也无法返回片段A. MainActivity直接关闭。 然而,我试图自己管理后台,没有运气。 我可以看到片段在堆栈上,但是如果我调用popBackStackImmediate() ,则popup片段A并且不执行片段事务。 (先回来什么都没发生,第二次活动结束)

我还附加了FragmentManager logcat:
http://pastebin.com/hFLHprL8

  • Android深度链接 - 后退堆栈
  • 从configuration改变片段后,现在共享FrameLayout?
  • 获取后栈中的最后一个片段
  • 如何在Android应用程序中find后台堆栈活动?
  • 活动破坏后的活动背后的不良行为
  • 从BackStack中保留ViewPager中的Fragment时重新加载WebView
  • 清除较旧SDK上的完整Android活动堆栈(缺少FLAG_ACTIVITY_CLEAR_TASK)
  • noHistory vs finish() - 哪个更受欢迎?
  • 对于那些仍在寻找解决方案的人。

    在主Activity类(托管片段)中,只需覆盖onBackPressed()

     @Override public void onBackPressed() { if (getFragmentManager().getBackStackEntryCount() > 0 ){ getFragmentManager().popBackStack(); } else { super.onBackPressed(); } } 

    片段中没有onBackPressed()方法,此方法仅适用于activity 。 因此,当我们按后退键时,会显示activity的默认行为,即

    您将转到上一个活动(如果有)或应用程序将退出。

    现在我们需要覆盖这个方法来告诉activity当我们按下后退键时,如果后面的堆栈中有任何片段,则将它们popup(这是addToBackStack()进入图片的时候)。 否则请遵循默认行为。

    试试这个(注意为fragmentA 添加替换,为fragmentB 添加 addToBackStack()

     StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment fragmentManager.beginTransaction() .add(R.id.content_frame, list) .commit(); 

     StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment ... fragmentManager.beginTransaction() .replace(R.id.content_frame, fragment) .addToBackStack("FragmentB") .commit(); 

    我不得不手动调用FragmentManager beginTransaction()commit()
    通过覆盖onBackPressed()解决:

     @Override public void onBackPressed() { ... if (fragmentManager.getBackStackEntryCount() > 1){ fragmentManager.popBackStackImmediate(); fragmentManager.beginTransaction().commit(); } else { //handle finish finish(); // Closes app } } 

    如果您正在与addToBackStack()和popBackStack()进行斗争,那么只需使用

     FragmentTransaction ft =getSupportFragmentManager().beginTransaction(); ft.replace(R.id.content_frame, new HomeFragment(), "Home"); ft.commit();` 

    在你的活动中OnBackPressed()通过标签找出fargment,然后做你的东西

     Fragment home = getSupportFragmentManager().findFragmentByTag("Home"); if (home instanceof HomeFragment && home.isVisible()) { // do you stuff } 

    有关更多信息, 请访问https://github.com/DattaHujare/NavigationDrawer我从不使用addToBackStack()来处理片段。

    popBackStack()popBackStackImmediatly()的原因是你没有将该片段(你要popup)添加到backStack。 为了做到这一点,你必须在使事务添加/替换你的片段时调用addToBackStack()。