編集画面で保存せずに戻るときに確認ダイアログを出したい
ユーザー入力を伴う画面で戻るボタンをクリックしたとき、編集内容が消えてしまうのを通知して、 ユーザーに本当に戻るか、画面にとどまるかを選択させたい。
デフォルトでは戻るボタンは問答無用に前の画面に戻るので、処理を止めつつダイアログを出す必要がある。
ホームボタンクリック時の処理を変える
Fragment#onOptionsItemSelected()
をオーバライドすることでホームボタンクリック時の処理を変更できる。
主な流れは以下の通り。
setHasOptionMenu(true)
でメニューボタンのハンドリングを有効化するFragment#onOptionsItemSelected()
をオーバライドする- 実装してホームボタンクリック時(
android.R.id.home
)で確認ダイアログを出す - 実装してホームボタンクリック時(
android.R.id.home
)でtrue
を返す
参考: 【Android,Kotlin】onOptionsItemSelectedでtrueを返すとホームボタンが反応しなくなる
実装
このような場合はホームボタンをクリックしたときはダイアログを出すだけで画面移動はしないようにしたい。
そしてOKボタンをクリックしたときのみ前の画面へ戻るようにしたい。
以下のようにホームボタンクリック時にtrue
を返せば実現できる。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
val context = context ?: return false
MaterialAlertDialogBuilder(context).apply {
setMessage("編集内容が破棄されますがよろしいですか?")
setPositiveButton("OK") { _, _ ->
findNavController().popBackStack() // OKをクリックしたときに戻る
}
setNegativeButton("キャンセル") { _, _ -> }
}.show()
true // ← true を返すことで戻らなくなる
}
else -> super.onOptionsItemSelected(item)
}
}
実装(MenuProvider)
MenuProvider
利用時も考え方は同じ。
onMenuItemSelected
でtrue
を返しつつダイアログを表示する。
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 -> {
val context = context ?: return false
MaterialAlertDialogBuilder(context).apply {
setMessage("編集内容が破棄されますがよろしいですか?")
setPositiveButton("OK") { _, _ ->
findNavController().popBackStack() // OKをクリックしたときに戻る
}
setNegativeButton("キャンセル") { _, _ -> }
}.show()
true // true を返すと戻らなくなる
}
else -> false
}
}
},
viewLifecycleOwner,
Lifecycle.State.RESUMED
)
OSのバックボタンでも確認ダイアログを出す
Android OSには標準のバックボタンもあるので、そちらの対処も必要となる。
Android OS標準のバックボタンにフックして実行するにはActivity#onBackPressedDispatcher
にコールバックを登録する。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.onBackPressedDispatcher?.addCallback(this) {
val context = context ?: return@addCallback
MaterialAlertDialogBuilder(context).apply {
setMessage("編集内容が破棄されますがよろしいですか?")
setPositiveButton("OK") { _, _ ->
findNavController().popBackStack() // OKをクリックしたときに戻る
}
setNegativeButton("キャンセル") { _, _ -> }
}.show()
}
}
\確かな知識を身に着けたい、Androidアプリ開発を学びたい人にオススメ!/