【Android】テキスト入力が正しくない時に該当のEditTextにエラーを表示する

# 概要
例えばログインフォームで情報を入力してログインしようとした時に、メールアドレスやパスワードが間違っていた場合などにエラーメッセージを表示したい。該当項目の入力欄の近くに表示する方法をまとめる。
![スクリーンショット 2020-02-28 17.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/a94848b7-5037-0f6c-3b3d-4b673e452fce.png)

今回はマテリアルデザインの[`TextInputLayout`](https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout)を用いた。

# EditTextにエラーを表示する
```fragment_form.xml
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/emailField"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="メールアドレス"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
                <EditText
                    android:id="@+id/emailText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textEmailAddress"/>
            </com.google.android.material.textfield.TextInputLayout>
            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/passwordField"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="パスワード"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
                <EditText
                    android:id="@+id/passwordText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPassword"/>
            </com.google.android.material.textfield.TextInputLayout>
        </LinearLayout>
```

`setError("string")`（もしくは`textInputLayout.error = "string"`）で、エラーを表示させたいEditTextの外側のTextInputLayoutにエラー文をセットする。

```FormFragment.kt
class FormFragment : Fragment() {
    private lateinit var emailTextInput: TextInputLayout
    private lateinit var emailEditText: EditText
    private lateinit var passwordTextInput: TextInputLayout
    private lateinit var passwordEditText: EditText

    ... (略)

    private fun setError() {
        if (emailEditText.text.isEmpty()) {
            emailTextInput.setError("メールアドレスを入力してください")
        } else if (emailEditText.text.toString() == "a") {
            emailTextInput.error = "aです"
        }
        if (passwordEditText.text.isEmpty()) {
            passwordTextInput.setError("パスワードを入力してください")
        }
    }
}
```

これで、該当のEditTextの下にエラーメッセージが表示される。
![スクリーンショット 2020-02-28 18.00.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/f369f863-b0dd-8ad2-02d5-fc15f6d750a2.png)


## おまけ: 共通エラー表示
例えば、ログインしようとしてサーバとの通信に失敗した時に「通信に失敗しました」などと表示したいことがある。
その場合は`TextView`などを置いて失敗した時にエラーメッセージをセットすれば良い。

```fragment_form.xml
    ... (略)
        <TextView
            android:id="@+id/login_form_error_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#FF0000" />
    </LinearLayout>
```

```FormFragment.kt
    private fun setError() {
        if (emailEditText.text.isEmpty() && passwordEditText.text.isEmpty()) {
            errorText.text = "通信に失敗しました"
        } else {

        ... (略)
```

![スクリーンショット 2020-02-28 18.17.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/716d8fda-4f85-0de4-4594-344d9402226b.png)


余談: 背景色が緑色なのは、[これ](https://qiita.com/mmmmk/items/d35e7234cb0672d6d5ef)と同じプロジェクトを使っており、Fragmentの別を分かりやすくするためであるが、今回は別Fragmentは必要なかった。
上記リンクの記事には赤背景と青背景のFragmentが登場する。<font color="#808080">次何色にしよう</font>

# まとめ
TextInputLayoutを使って、EditTextにエラーを表示した。