LoginSignup
8
8

More than 3 years have passed since last update.

【Android】 MaterialAlertDialogで色々実装する

Last updated at Posted at 2020-04-11

MaterialDialogに関してこういうレイアウトを作りたいと思った時に
どうしたらいいのか忘れることがあったのでレシピブック的な感じでまとめてみました.

Dialogの導入

依存の追加

まずは作成したプロジェクトのbuild.gradleにMaterialDesignの依存を追加します.

build.gradle
dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
    // ...
}

<version>には現在のバージョンを記載します.
執筆時点(4月10日)では安定版が1.1.0となります.
最新版についてはGithubのリリースページから確認できます.

Themeの変更

MaterialDialogを使用するには使用するActivityがMaterialDesign系のテーマを継承している必要があります.
今回はテーマにTheme.MaterialComponents.Lightを継承させます.

MaterialDialogの基本

タイトル+メッセージ

Material Alert DialogはBuilderパターンにより実装されています.以下のようにタイトル, メッセージ本文を指定し、最後にshow()を書くことで表示させることができます.

MainActivity.kt
MaterialAlertDialogBuilder(this)
        .setTitle("タイトル")
        .setMessage("メッセージ内容\nここに表示される文字は自動で改行されるようになっています.")
        .show()

ボタンを追加する


またポジティブボタンは一行setPositiveButton(“ボタン名", タップ時のリスナー)を加えることで実装することができます.

MainActivity.kt
MaterialAlertDialogBuilder(this)
        .setTitle("タイトル")
        .setMessage("メッセージ内容\nここに表示される文字は自動で改行されるようになっています.")
        .setPositiveButton("はい") { dialog, which ->

        }
        .setNegativeButton("キャンセル", null)
        .show()

setPositiveButtonの第2引数にはDialogInterfaceのリスナーを持つことができますし、上記のようにラムダっぽく書くこともできます.
また第2引数はnullableとなっているため、キャンセルの場合など特に何もさせたくない場合はnullとすることができます.

またボタンの色はアプリで指定しているcolorPrimaryの色になります.

様々な表示パターン

複数のボタン


AlertDialogに複数のボタンを配置して、それぞれで異なる動きをさせたい場合ニュートラルボタンというオプショナルなボタンも追加することができます.

ラジオボタン


AlertDialogの中に複数のラジオボタン(一つのみ選択できるボタン)を作ることができます.

setSingleChoiceItems(選択肢の配列, 最初に選択されている番号, 選択時のリスナー)
他のボタンと同様に選択時のリスナーnullにすることもできます.

選択時のリスナーのラムダ式での引数のdialogはダイアログ自体、whichは選択したアイテムが何番目であるかの情報が渡ってきます.

MainActivity.kt
MaterialAlertDialogBuilder(this)
        .setTitle("タイトル")
        .setSingleChoiceItems(arrayOf("桃", "りんご", "梨"), 0) { dialog, which ->

        }
        .setPositiveButton("はい") {dialog, which ->

        }
        .setNegativeButton("キャンセル", null)
        .show()

また下部のポジティブ、ネガティブボタンを使用せず、ダイアログ内の選択肢を選択してダイアログを閉じることができます.

選択時のリスナーの引数で渡されるdialogdismiss()メソッドを呼び出すことで閉じることができます.
ダイアログを閉じる前にどの選択肢を選択したのかを取得する必要があります.

MainActivity.kt
MaterialAlertDialogBuilder(this)
        .setTitle("タイトル")
        .setSingleChoiceItems(arrayOf("桃", "りんご", "梨"), 0) { dialog, which ->
            doSomething(which)
            dialog.dismiss()
        }
        .show()

ちなみにボタンの色はAcentColorが使用されます.

チェックボックス

チェックボックスの場合はsetMultiChoiceItemsを追加することで追加できます.
setMultiChoiceItemsの引数には
第1引数: 項目リスト
第2引数: 選択状態の初期状態(真偽値配列)
第3引数: 選択時のリスナー
の3つを必要とします.

また無名関数から受け取る引数でisCheckedがあります.
項目を選択した場合に選択状態であるかが渡されてきます.

MainActivity.kt
MaterialAlertDialogBuilder(this)
        .setTitle("タイトル")
        .setMultiChoiceItems(arrayOf("桃", "りんご", "梨"), booleanArrayOf(false, false, false)) {dialog, which, isChecked ->

        }
        .setPositiveButton("決定") { dialog, which ->

        }
        .show()

シンプルなリスト表示

シンプルなリスト表示はsetItemsによりリストに入れる配列と、リストをタップした際のリスナーを引数とすることで実装することができます.

MainActivity.kt
MaterialAlertDialogBuilder(this)
                .setTitle("タイトル")
                .setItems(arrayOf("桃", "りんご", "梨", "さくらんぼ", "オレンジ")) { dialog, which ->

                }
                .show()

カスタムリスト


上のようなカスタムリストはアダプターを作成することで実装することができます.

まずカスタムアダプターを作成します.
本記事では画像のような果物の画像とテキストを使用したアダプターを作成します

FruitItemAdapter.kt
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として作成しています.

MainActivity.kt
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に作成したアダプターをセットします

MainActivity.kt
MaterialAlertDialogBuilder(this)
    .setTitle("タイトル")
    .setAdapter(adapter) { dialog, which ->

    }
    .show()
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8