即使使用FragmentTransaction.addToBackStack(),后退按钮也会关闭应用程序

时间:2014-05-19 00:30:49

标签: android android-fragments back-button back-stack

我在stackoverflow上读到的其他问题都没有能够解决我的问题。据我所知,我正在做的一切正确。

我有片段的主/细节流。

创建主活动后,主片段将加载以下代码:

    Fragment frag;
    frag = new MainListFragment();//<-- **the master fragment**

    FragmentManager fm = getFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.replace(R.id.fragment_container, frag);
    Log.d("My Debug Bitches", "stack:" + fm.getBackStackEntryCount());
    transaction.commit();

主片段有ListView;单击列表项会显示详细信息片段,如下所示:

@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
    super.onListItemClick(listView, view, position, id);


    FragmentManager fm = getFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    SubListFragment frag = new SubListFragment();//<-- **the detail fragment**

    transaction.replace(R.id.fragment_container, frag);
    transaction.addToBackStack(null);
    transaction.commit();
    fm.executePendingTransactions();
    Log.d("My Debug Bitches", "stack:" + fm.getBackStackEntryCount());

}

现在,根据LogCat,从主片段导航到详细片段后,BackStackEntryCount 从0更改为1 enter image description here

那么为什么当我在细节片段中单击后退按钮时,应用程序关闭而不是返回到主片段?

2 个答案:

答案 0 :(得分:57)

您必须将popBackStack()调用添加到活动的onBackPressed()方法中。

例如:

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

答案 1 :(得分:0)

@ Bobbake4的答案很棒,但有一个小问题。 假设我有三个片段A,B和C. A是主要片段(我启动应用程序时显示的片段),B和C是我可以从导航抽屉或A导航到的片段。 现在,当我使用B或C的后退按钮时,我回到上一个片段(A)好了,但是前一个片段(片段B或C)的标题现在显示在片段A的actionBar标题中。我有再次按下后退按钮以“真正”完成后退导航(显示视图并更正片段的标题并返回)

这就是我解决这个问题的方法。声明这些变量。

 public static boolean IS_FRAG_A_SHOWN = false;
 public static boolean IS_FRAG_B_SHOWN = false;
 public static boolean IS_FRAG_C_SHOWN = false;

在我处理导航抽屉方法的app的MainActivity中,我有一个方法displayView(position)来处理片段的切换。

private void displayView(int position) {
    IS_FRAG_A_SHOWN = false;
    IS_FRAG_B_SHOWN = false;
    IS_FRAG_C_SHOWN = false;
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new FragmentA();
            IS_FRAG_A_SHOWN = true;
            break;
        case 1:
            fragment = new FragmentB();
            IS_FRAG_B_SHOWN = true;
            break;
        case 2:
            fragment = new FragmentC();
            IS_FRAG_C_SHOWN = true;
            break;

        default:
            break;
    }

最后,在我的onBackPressed方法中,我这样做:

public void onBackPressed() {
    if(fragmentManager.getBackStackEntryCount() != 0) {
        fragmentManager.popBackStack();
        if (IS_FRAG_A_SHOWN) { //If we are in fragment A when we press the back button, finish is called to exit
            finish();
        } else  {
            displayView(0); //else, switch to fragment A
        }

    } else {
        super.onBackPressed();
    }
}