ラベル Fragment の投稿を表示しています。 すべての投稿を表示
ラベル Fragment の投稿を表示しています。 すべての投稿を表示

2022年8月20日土曜日

Android deprecatedとされたsetTargetFragmentを推奨先に変える方法を解説

どうも。どっことです。今回はdeprecatedとなっているFragment#setTargetFragmentの移行対応について解説します。

setTargetFragmentの移行対応について

複数のFragmentを使って画面遷移を実装するとき、遷移先の画面で決めたことを遷移元の画面に教えてあげたいときがあります。たとえば

  • 設定画面で設定の要素をタップしたらそれに関する設定値の一覧が表示される。
  • ユーザは一覧から設定項目を選択する。
  • 選択した値を設定画面に返してあげて、設定画面にはユーザが選択したものを最新の設定値として表示する。

などですね。

これまではFragment間のデータのやりとりはtargetFragmentを使うことで実現できました。呼び出し元のFragmentを遷移先から参照できるようにして、その参照から呼び出しもとにデータを返してあげる。という具合です。

さて、「これまでは」と書いた通り、このメソッドdeprecated(非推奨)になってしまいました。これの扱いが簡単だったので個人的に非常にありがたかったのですが、Google様のお達しなので、今後は推奨されるやり方で実装する必要があります。今回は備忘録も含め、新しい実装方法を載せたいと思います。

解説

以下の順に解説していきます。

  1. 呼び出される側の実装
  2. 呼び出す側の実装
    1. Activity → Fragmentの場合
    2. Fragment → Fragmentの場合

呼び出される側の実装

parentFragmentManager.setFragmentResult("request_key", Bundle())    

呼び出される側の実装はシンプルで、(自身を管理している)parentFragmentManagerに渡したいデータを設定します。 通知したい情報をBundleに詰める必要があるため、上記の例は必要最低限のスニペットです。

呼び出す側の実装

Activity -> Fragment の場合

supportFragmentManager.setFragmentResultListener("request_key", this) { _, result ->
    // result を参照して結果を処理する
}

呼び出すFragmentActivityが持っているsupportFragmentManagerが管理しているので、それに対してResultListenerをセットしてあげます。ActivityDialogFragmentを表示するときは上記の実装になります。

Fragment -> Fragment の場合

childFragmentManager.setFragmentResultListener("request_key", this) { _, result ->
  // result を参照して結果を処理する
}

一方で Fragment -> Fragment の場合はちょっとだけ注意が必要です。呼び出すFragmentを呼び出し元のFragmentが持つFragmentManager管理している場合、こちらの実装パターンが利用できます。例えばFragmentが、自身が持っているchildFragmentManagerを使ってDialogFragmentを表示するなどの場合は、こちらの実装が使えます。

ただし、表示するDialogFragentActivityが持っているsupportFragmentManagerが表示する場合、このパターンではなく Activity -> Fragmentのパターンで実装することになります。表示するDialogFragmentをどのFragmentManagerが管理するかが違うためです。

まとめ

今回はdeprecatedとなっているFragment#setTargetFragmentの移行について解説しました。開発期間が長いアプリケーションでは、まだまだsetTargetFragmentFragment間での結果のやり取りを処理しているものも多いのではないでしょうか。deprecatedとなっているメソッドのため、なるべく早めに解消しておきたいですね。

2022年8月4日木曜日

Android DialogFragmentをフルスクリーン化する実装方法を解説

どうも。どっことです。今回はDialogFragmentをフルスクリーン化する実装方法を解説します。

DiagloFragmentをフルスクリーンで表示する

DialogFragmentはダイアログを表示するためのクラスです。シンプルなダイアログを表示するために使うのはもちろんですが、自分で色々カスタマイズできる拡張性の高いクラスでもあります。今回は、そんなDialogFragmentをカスタマイズするために画面いっぱいに表示する実装(フルスクリーン化)を解説します。

実装方法

今回はまとめてスニペットを載せたいと思います。ポイントはonStart()です。
class CustomDialogFragment : DialogFragment() { 
  
  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return Dialog(requireActivity()).also { dialog ->
      // 表示したいViewをここで生成します。LayoutInflaterなどを使ってもOK
      val view = View(requireContext()) 
      dialog.setContentView(view)
    }
  }

  override fun onStart() {
    super.onStart()
    // onStart() で以下の処理をします。
    dialog?.window?.also {
       // ①背景色を背景透過にするよう設定(完全にフルスクリーンにするなら必要)
       it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
       // ②画面サイズに合わせて領域を広げる
       it.setLayout(
          ViewGroup.LayoutParams.MATCH_PARENT,
          ViewGroup.LayoutParams.MATCH_PARENT
       )
    }
  }
}

onStart①背景色を透過にする②表示領域を画面いっぱいに広げるように設定します。これにより表示するダイアログをフルスクリーン化することができます。

まとめ

今回はDialogFragmentのフルスクリーン化について解説しました。DialogFragmentは拡張性が高い反面、使いこなすのが非常に難しいクラスです。ただ正しく理解さえできれば一つ一つの処理は難しいものでは無いので、どんなカスタマイズでもできるようにマスターしていきたいですね。


移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。