web-dev-qa-db-ja.com

FragmentTransaction.addToBackStack()を使用している場合でもアプリを閉じる戻るボタン

私が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から1に変更: enter image description here

では、詳細フラグメント内で戻るボタンをクリックすると、マスターフラグメントに戻るのではなく、アプリが閉じるのはなぜですか??????????

15
scottyseus

popBackStack() 呼び出しをアクティビティの onBackPressed() メソッドに追加する必要があります。

例:

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

@ Bobbake4の答えは素晴らしいですが、小さな問題が1つあります。 3つのフラグメント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;
_

ナビゲーションドロワーメソッドを処理しているアプリの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();
    }
}
_