AndroidのダイアログにEditTextを追加する方法

AndroidのAlertDialogにEditTextを追加する方法を解説します。

まずは最も簡単な例をご紹介します。

```Sample.kt
val editText = AppCompatEditText(this)
AlertDialog.Builder(this)
                .setTitle("名前の変更")
                .setMessage("名前を入力してください。")
                .setView(editText)
                .setPositiveButton("OK") { dialog, _ ->
	                // OKボタンを押したときの処理
                    dialog.dismiss()
                }
                .setNegativeButton("キャンセル") { dialog, _ ->
　　　　　　          // キャンセルボタンを押したときの処理
                    dialog.dismiss()
                }
                .create()
                .show()
```

表示されるダイアログはこちらです。

![スクリーンショット 2021-07-19 131122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261074/fc3e1c2c-a76f-e860-1db7-8d430a04ae58.png)

この状態では入力欄がダイアログの幅いっぱいに広がっていますし、OKボタンも初めから有効化されているのが分かるかと思います。
また文字も無限に入力できてしまいます。

このあたりを調整したダイアログを今回は実装していきたいと思います。

具体的な実装内容は以下の通りです。

- EditTextの左右にマージンを16dpずつ設定する
- 入力された文字が1文字以上ならOKボタンを有効化する
- 未入力の時にhintを表示する
- 32文字以上入力できないようにする

コードは以下の通りです。

```Sample.kt
// ダイアログ専用のレイアウトを読み込む
val dialogLayout = LayoutInflater.from(this).inflate(R.layout.layout_common_edit_dialog, null)
val editText = dialogLayout.findViewById<AppCompatEditText>(R.id.editTextDialog)

// ダイアログ作成
val dialog = AlertDialog.Builder(this)
                    .setTitle("名前の変更")
                    .setMessage("名前を入力してください。")
                    .setView(dialogLayout)
                    .setPositiveButton("OK") { dialog, _ ->
                        // OKボタンを押したときの処理
                        dialog.dismiss()
                    }
                    .setNegativeButton("キャンセル") { dialog, _ ->
                        // キャンセルボタンを押したときの処理
                        dialog.dismiss()
                    }
                    .create()
                    dialog.show()

// ダイアログのボタンを取得し、デフォルトの色を「#000000」に設定
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getColor(R.color.black))
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getColor(R.color.black))

// AppCompatEditTextにTextChangedListenerをセット
editText.addTextChangedListener( object : TextWatcher {
                    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

                    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

                    override fun afterTextChanged(s: Editable?) {
                        // 1~32文字の時だけOKボタンを有効化する
                        if (s.isNullOrEmpty() || s.length > 32) {
                            dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
                            dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getColor(R.color.gray))
                        } else {
                            dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
                            dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getColor(R.color.black))
                        }
                    }
})
```

```layout_common_edit_dialog.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/editTextDialog"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:hint="1~32文字で入力してください"
        android:inputType="text"
        android:maxLength="32"
        android:maxLines="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

以下のようなダイアログが表示され、文字数に応じてOKボタンの有効/無効が切り替われば実装完了です。

![スクリーンショット 2021-07-19 130423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261074/12c60d1b-3bc6-8946-590d-490ed49ae7a0.png)