英数字以外が入力されたらエラー文を表示するEditTextを作ってみた

#はじめに
仕様としては「英数字以外が入力されたら、入力しようとした文字列は表示されずにキーボードが閉まわれてエラー文を表示する」プログラムです。

コードは一番下にgithubのURL貼ったのでコードだけ見たいって人はじゃんじゃんスクロールしちゃって下さい。

#EditTextを英数字しか入力出来ないようにする

InputFilterを使いました。

###まず何か入力された時のイベントを設定します。

```java
InputFilter inputFilter = new InputFilter() {
            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                //英数字の場合
                if (source.toString().matches("^[a-zA-Z0-9_]+$")) {
                    //入力値を問題なく返す
                    return source;
                }
                //英数字でない場合
                else {
                    //空白を返す
                    return "";
                }
            }
        };
```
ここのCharSequenceの各引数は下記の通りです。

| 引数              |       内容  |
|:-----------------:|:------------------:|
| source            |入力中の変換前の文字列|
| start             |入力中の文字列の先頭の位置(基本的に0)| 
| end               |入力中の文字列の長さ| 
| dest              |入力中も含めたEditText内の文字列|  
| dstart            |入力中の文字列の先頭のEditText内での位置|
| dend              |入力中の文字列の終端のEditText内での位置|

###次にFilterを作成します。

```java
//設定したイベントからFilterの作成
InputFilter[] filters = { inputFilter };
```

###EditTextにセットします。

```java
//作成したFilterのセット
editText.setFilters(filters);
```

###gradleの編集
このまま実行しても参照する文字データが無いので実行されません。
なのでgradleに下記を追加します。

```java
defaultConfig {
　　　　 //省略
        jackOptions {
            enabled true
        }
```
```java
android {
    //省略
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
```

#EditTextにエラーを表示させる

TextInputLayoutを使いました。

###EditTextに適用させる。

使用するEditTextを囲むだけで出来ます。

```xml
<android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

</android.support.design.widget.TextInputLayout>
```

EditText内にヒントを書けば自動的にアニメーションも適用してくれます。

```xml
<EditText
  　 android:layout_width="match_parent"
  　 android:layout_height="match_parent"
　　 android:hint="英数字限定"/>
```

###gradleの編集
参照するデザインが無いので(以下略

```java
dependencies {
    //省略
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:23.4.0'
}
```
23.4.0の所は自分のバージョンに変更して下さい。

#エラー文の表示
TextInputLayoutに含まれてるエラー表示を使いました。

###InputLayoutの宣言と関連付け

```java
TextInputLayout inputLayoutTest= (TextInputLayout)findViewById(R.id.inputLayoutTest)
```

###エラー文の変更
```java
//エラー文
inputLayoutTest.setError("error");
```

###エラー文の表示/非表示
```java
//エラー文を表示
inputLayoutTest.setErrorEnabled(true);
//エラー文を非表示
inputLayoutTest.setErrorEnabled(false);
```

###エラー文の注意点
エラーを消す時に.setErrorEnabled(false)で消してしまうと、trueにしても表示されなくなりました。
どうやら.setErrorEnabled(false)はView.GONEと同じ処理をしているみたいです。
とりあえず自分は

```java
inputLayoutTest.setError("");
```
で表示文字を空白にして疑似的に消えてるように見せる処理を行ってますが、これだと表示領域が残ったままで気持ち悪いので今後直していくつもりです・・・

#キーボード制御
InputMethodManagerを使ってます。

###InputMethodManagerの宣言と関連付け

```java
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
```

###キーボードの非表示
```java
//キーボードを閉じる
inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), InputMethodManager.RESULT_UNCHANGED_SHOWN);
```

#おわりに
ほぼ自分のメモ代わりに書きました。

github/EditFilterTest
https://github.com/TaigaNatto/EditFilterTest