Androidで戻るボタン(BackKey)を押した際の挙動でハマったので、その実装方法を記載します。

 

[前提]

画面の作りは、Fragmentを利用。

Fragmentの切り替えは普通にこんな感じで実装。

mFragmentManager.beginTransaction()

            .replace(R.id.container, myFragment).commit();

[ゴール]

戻るボタンを押した際に、一つ前のFragmentを再度表示したい。

[問題]

戻るボタンを押すとActivityがバックグラウンド実行状態に移行してしまう。(ホームボタンが押された時と同じ挙動をする。)

[解決法]

1.BackStackへの追加

ネットで情報を調べて見ると、次のFragmentをcommitする前にBackStackへ現在のFragmentを追加する必要があるとのこと。

mFragmentManager.beginTransaction()

            .addToBackStack(null) // ここでBackStackに追加している。

            .replace(R.id.container, myFragment).commit();

これで解決するかと思ったが、以前として同じ挙動のまま。

そこでもう少し調べてみることに。

2.onBackPressedの実装

戻るボタンが押されるとイベントが発生するので、それをキャッチして元のFragmentへ戻るようにコーディングすればよさそう。

FragmentのViewに対してOnClickListenerでリスナー登録する例が有ったが、戻るボタンを押してもうまくListenerが呼ばれない。

Activity側で実装をするとよいとの情報があったので、以下のように実装しました。

@Override

public void onBackPressed() {

    // super.onBackPressedを呼んではいけない(Activityを終了させてしまうため)

    int backStackCnt = getFragmentManager().getBackStackEntryCount();

    if (backStackCnt != 0) {

      getFragmentManager().popBackStack(); // BackStackに乗っているFragmentを戻す

    }

}

コード内にコメントを記載しましたが、戻るボタンを押すとアプリが終了してしまった原因はActivityで元々定義されているonBackPressedの処理でした。

これをOverrideすることで、無事解決しました。

なお、ここではmFragmentManager.beginTransaction()の後のFragment設定時に.replaceとしているため、BackStackがpopされたときには元のFragmentがリロードされます。

元のFragmentで初回表示時に通信等を行っている場合は、その処理も再度発生してしまいます。(FragmentのCreateから再実行される)

replaceではなくaddを利用すれば、元のFragmentは破棄されず裏に隠れた状態になるため、リロードされません。

実装方法選択時には、リロード時の負荷/ユーザビリティとFragmentの保持に必要なメモリ量の兼ね合い化となります。

Leave a Reply

Your email address will not be published. Required fields are marked *