ホームボタン(戻るボタン)をクリックしても反応しない事象が発生

Navigation Componentを利用時、戻るボタンをクリックしても前の画面に戻れない場合がある。

ホームボタン

原因: Fragment#onOptionsItemSelectedでtrueを返している

ホームボタンはデフォルトで戻るはずなので、もし戻らないとしたらホームボタンクリック時の処理を止める コードが書かれている可能性がある。

遭遇したのは以下の通り。

Fragment#onCreatesetHasOptionMenu(true)を呼んでメニューのクリック処理をハンドリングできるようにしておいて…

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setHasOptionsMenu(true)
}

onOptionsItemSelectedでホームボタン(android.R.id.home)がクリックされたときにtrueを返す。

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        android.R.id.home -> true
        else -> super.onOptionsItemSelected(item)
    }
}

以上の実装でホームボタンをクリックしても何も反応せず、前の画面に戻れなくなる。

Fragment#onOptionsItemSelected()の戻り値true/false

Fragment#onOptionsItemSelected()の戻り値でtrueを返すと「処理を続行しない」ということになる。
逆にfalseを返すと処理を続行して関連するActivity/FragmentonOptionsItemSelectedが呼ばれる。

上記例ではtrueを返したがために処理が続行されず通常の戻る動作が実行されない。

MenuProviderでメニューの処理を実装しているときも同様。

MenuProvider#onMenuItemSelectedtrueを返すと処理が続行されず、ホームボタンをクリックしたときでも戻らなくなる。

activity?.addMenuProvider(
    object : MenuProvider {
        override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
            inflater.inflate(R.menu.menu_main, menu)
        }

        override fun onMenuItemSelected(item: MenuItem): Boolean {
            return when (item.itemId) {
                android.R.id.home -> true // true を返すと戻らなくなる
                else -> false
            }
        }
    },
    viewLifecycleOwner,
    Lifecycle.State.RESUMED
)

参考: 【Android,Kotlin】メニューの処理をMenuProviderにする

戻っていいのか確認するダイアログを出すパターンで使える

trueを返すとホームボタンで戻らなくなる、というのは確認ダイアログを出したいときに使える。
イメージとしては編集画面などユーザーの入力を求める画面において、 未保存の状態でホームボタンが押されたときに以下のようなダイアログを出したい場合。

確認ダイアログ

戻るボタンをクリックして戻ってしまうとダイアログが出せないので、trueを返すことで戻らなくしておき、 代わりにダイアログを表示する処理を入れることで実現できる。

実装については以下を参照。

» 【Android,Kotlin】Navigation Component利用時に戻るボタンで確認ダイアログを出す