👻

JetpackCompose レスポンスの返り値でAlertDialog出したいけど各画面に何個も作りたくない場合の対処法

2021/10/08に公開

諦めてMaterialDialogなりAlertDialog.Builderなりを使おう。

残念ながらJetpackComposeのDialogは、

各画面に持ってて基本はifで消してるみたいな処理になっているので、

レスポンスの返り値によって全画面にDialog出したいけど全画面に持たせるのだるいよ......

って場合は既存のDialogを使うことで対処ができる。

でもDialogFragment作ってxmlいじってどうのこうのしたくない場合

コードで書けます。

サンプルコード

val imageView = ImageView(activity)
                imageView.setImageResource(R.drawable.hogehoge_logo)

                val textView = TextView(activity)
                textView.apply {
                    text = "タイトル"
                    textSize = 16F
                    typeface = Typeface.DEFAULT_BOLD
                }

                val linearLayout = LinearLayout(activity)
                linearLayout.apply {
                    orientation = LinearLayout.VERTICAL
                    gravity = Gravity.CENTER;
                    layoutParams = LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.MATCH_PARENT
                    )
                    addView(imageView)
                    addView(textView, LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT))
                }

                activity?.let {
                    MaterialAlertDialogBuilder(it)
                        .setCustomTitle(linearLayout)
                        .setMessage(
                            "ここに色んな内容が入るよ。
			    \nメインの文言だよ。
			    \nほげほげ〜〜〜〜"
                        )
		                .setNegativeButton("ネガティブボタンだよ") { _, _ ->
				
				}
                        .setPositiveButton("ポジティブボタンだよ"){ _, _ ->
                            // やりたい処理を書こう
                        }
                        .setCancelable(false)
                        .show()
                }

setCustomTitleにはViewを入れることができるので、

linearLayoutを生成してそこに色々定義し、

ImageViewとTextViewを縦に並べてヘッダーに画像があって

下にタイトルがあるみたいなデザインを実現している。

後はレスポンスによって内容変えたいなら関数にしてしまって、

受け取った値を表示したいところに入れればおk

でも残念ながらMaterialDialogベースの場所は色の変更ができない

できるはできるのですが、

やろうと思うとThemeにstyle作ってxmlで定義しないといけないので、

結局少量ではあるがxmlを触るはめになってしまう......

今更ながらComposeでの解決方法

書いてて思いついたので一応メモ書きとして......

全画面で使う共通ベースレイアウトCompose関数にDialogを持たせて、

そこの引数にMutableStateFlowでBoolean渡せばいけるのではという話

根幹で色々考慮して考えておく必要がありますね......

参考記事

https://material.io/components/dialogs/android#using-dialogs

https://qiita.com/hokutonikukyu/items/ebbc0318c07035e04bf7

https://qiita.com/kaleidot725/items/92f0716bd234c90932ab

https://zenn.dev/m_coder/articles/article-zenn-custom-dialog-by-dialogfragment

https://qiita.com/ohwada/items/f95518b6948b271433a3

https://www.section.io/engineering-education/getting-started-with-dialogs-in-android-kotlin/

https://developersdome.com/material-dialogs-in-android-with-example/#2_Alert_Dialog

https://petamind.com/material-design-custom-alert-dialog/

https://qiita.com/asukahime1021/items/8034341b55ebe4f7cc5c

https://qiita.com/ushi3_jp/items/c7f597a8cf3b35cce426

Discussion