🍋
【Android】ダイアログの呼び出しをシンプルに記述する方法:Result API周りを呼び出し先に隠蔽する
概要
Android開発では、FragmentからDialogを呼び出し、Dialogが閉じた後にFragmentに通知するケースがよくあります。
この記事では、その処理を簡潔に行う方法を紹介します。
Fragment間の通信にはFragment Result APIを使用します。
元の実装
呼び出し元
呼び出し元のFragmentで、childFragmentManagerにリスナーを設定し、Dialogを表示します。
Fragment
childFragmentManager.setFragmentResultListener(
DialogFragment.REQUEST_KEY,
viewLifecycleOwner
) { requestKey: String, bundle: Bundle ->
// Dialogが閉じたときの処理
val result = bundle.getParcerable<DialogFragment(DialogFragment.BUNDLE_KEY)
..
}
DialogFragment.newInstance().show(childFragmentManager, DialogFragment.TAG)
呼び出し先
呼び出し先のDialogで、setFragmentResultに返したい値を渡します。
(以下は、ダイアログが閉じたことだけを通知する場合の実装例です)
DialogFragment
parentFragmentManager.setFragmentResult(
REQUEST_KEY,
bundleOf(BUNDLE_KEY to "")
)
dismiss()
改善後の実装
先述のとおり、今回はダイアログが閉じたことだけを呼び出し元のFragmentに通知するとします。
そこでFragment Result API周りの処理をDialogFragment側に隠蔽し、ラムダでコールバックする実装にしました。
resultではなくdismissそのものを通知するイメージです。
呼び出し元
Fragment側でDialogを呼び出す処理はこれだけになります。
Fragment
DialogFragment.newInstance().show(
targetFragment = this,
onDismissDialog = {
// Dialogが閉じたときの処理
}
)
呼び出し先
DialogFragmentの実装は以下の通りです。
DialogFragment
fun show(targetFragment: Fragment, onDismissDialog: () -> Unit) {
targetFragment.childFragmentManager.setFragmentResultListener(
REQUEST_KEY,
targetFragment.viewLifecycleOwner
) { requestKey: String, bundle: Bundle ->
if (bundle.containsKey(BUNDLE_KEY)) {
onDimissDialog()
}
}
show(targetFragment.childFragmentManager, TAG)
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
parentFragmentManager.setFragmentResult(
REQUEST_KEY, bundleOf(BUNDLE_KEY "")
)
}
呼び出し元の実装がシンプルになりました🎉
参考
Discussion