MaterialDialogに関してこういうレイアウトを作りたいと思った時に
どうしたらいいのか忘れることがあったのでレシピブック的な感じでまとめてみました.
Dialogの導入
依存の追加
まずは作成したプロジェクトのbuild.gradle
にMaterialDesignの依存を追加します.
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
// ...
}
<version>
には現在のバージョンを記載します.
執筆時点(4月10日)では安定版が1.1.0
となります.
最新版についてはGithubの[リリースページ](Releases · material-components/material-components-android · GitHub)から確認できます.
Themeの変更
MaterialDialogを使用するには使用するActivityがMaterialDesign系のテーマを継承している必要があります.
今回はテーマにTheme.MaterialComponents.Light
を継承させます.
MaterialDialogの基本
タイトル+メッセージ

Material Alert DialogはBuilderパターンにより実装されています.以下のようにタイトル
, メッセージ本文
を指定し、最後にshow()
を書くことで表示させることができます.
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setMessage("メッセージ内容\nここに表示される文字は自動で改行されるようになっています.")
.show()
ボタンを追加する

MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setMessage("メッセージ内容\nここに表示される文字は自動で改行されるようになっています.")
.setPositiveButton("はい") { dialog, which ->
}
.setNegativeButton("キャンセル", null)
.show()
setPositiveButton
の第2引数にはDialogInterface
のリスナーを持つことができますし、上記のようにラムダっぽく書くこともできます.
また第2引数はnullable
となっているため、キャンセルの場合など特に何もさせたくない場合はnull
とすることができます.
またボタンの色はアプリで指定しているcolorPrimary
の色になります.
様々な表示パターン
複数のボタン

ラジオボタン

setSingleChoiceItems(選択肢の配列, 最初に選択されている番号, 選択時のリスナー)
他のボタンと同様に選択時のリスナーはnull
にすることもできます.
選択時のリスナーのラムダ式での引数のdialog
はダイアログ自体、which
は選択したアイテムが何番目であるかの情報が渡ってきます.
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setSingleChoiceItems(arrayOf("桃", "りんご", "梨"), 0) { dialog, which ->
}
.setPositiveButton("はい") {dialog, which ->
}
.setNegativeButton("キャンセル", null)
.show()
また下部のポジティブ、ネガティブボタンを使用せず、ダイアログ内の選択肢を選択してダイアログを閉じることができます.
選択時のリスナーの引数で渡されるdialog
のdismiss()
メソッドを呼び出すことで閉じることができます.
ダイアログを閉じる前にどの選択肢を選択したのかを取得する必要があります.
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setSingleChoiceItems(arrayOf("桃", "りんご", "梨"), 0) { dialog, which ->
doSomething(which)
dialog.dismiss()
}
.show()
ちなみにボタンの色はAcentColor
が使用されます.
チェックボックス

チェックボックスの場合はsetMultiChoiceItems
を追加することで追加できます.
setMultiChoiceItems
の引数には
第1引数: 項目リスト
第2引数: 選択状態の初期状態(真偽値配列)
第3引数: 選択時のリスナー
の3つを必要とします.
また無名関数から受け取る引数でisChecked
があります.
項目を選択した場合に選択状態であるかが渡されてきます.
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setMultiChoiceItems(arrayOf("桃", "りんご", "梨"), booleanArrayOf(false, false, false)) {dialog, which, isChecked ->
}
.setPositiveButton("決定") { dialog, which ->
}
.show()
シンプルなリスト表示

シンプルなリスト表示はsetItems
によりリストに入れる配列と、リストをタップした際のリスナーを引数とすることで実装することができます.
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setItems(arrayOf("桃", "りんご", "梨", "さくらんぼ", "オレンジ")) { dialog, which ->
}
.show()
カスタムリスト

まずカスタムアダプターを作成します.
本記事では画像のような果物の画像とテキストを使用したアダプターを作成します
class FruitItemAdapter(context: Context, private val layoutResourceId: Int, private val fruits: List<FruitItem>) :
ArrayAdapter<FruitItem>(context, layoutResourceId, fruits) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView
?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(layoutResourceId, null)
val item = fruits[position]
val imageView = viewfindViewById<ImageView>(R.id.imageView)
val textView = view.findViewById<TextView>(R.id.fruitText)
imageView.setImageResource(item.image)
textView.text = item.name
return view
}
}
data class FruitItem(val name: String, val image: Int)
続いて、果物のリストを作成し、そこからアダプターのインスタンスを生成します.
画像とテキストのカスタムレイアウトもview_fruit_item
として作成しています.
val fruits = listOf(
FruitItem("桃", R.drawable.furit_mark15_momo),
FruitItem("りんご", R.drawable.fruit_apple),
FruitItem("梨", R.drawable.fruit_nashi),
FruitItem("さくらんぼ", R.drawable.furit_mark17_cherry),
FruitItem("オレンジ", R.drawable.furit_mark18_mikan)
)
val adapter = FruitItemAdapter(this, R.layout.view_fruit_item, fruits)
最後にMaterialAlertDialogに作成したアダプターをセットします
MaterialAlertDialogBuilder(this)
.setTitle("タイトル")
.setAdapter(adapter) { dialog, which ->
}
.show()