片段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

Related of "片段addToBackStack()和popBackStackImmediate()不起作用"

对于那些仍在寻找解决方案的人。

在主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()。