読者です 読者をやめる 読者になる 読者になる

woshidan's blog

そんなことよりコードにダイブ。

AutoCompleteTextView.Validatorで遊ぶ

まだまだバリデーションしたい欲があるので、EditTextを拡張してプライベート変数として自作クラスのvalidatorを持たせようとした瞬間、Android StudioAutoCompleteTextView.Validator なるものがある、と教えてくれたので調べてみる所存です。

参考:

AutoCompleteを使う « Tech Booster

Y.A.M の 雑記帳: Android AutoCompleteTextView で候補に入力履歴を表示する

AutoCompleteTextView | Android Developers

まず簡単に書いてみる

まず、一番簡単な形を書いてみます。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
        AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_text_view);
        textView.setAdapter(adapter);
    }

    private static final String[] COUNTRIES = new String[] {
            "Belgium", "France", "Italy", "Germany", "Spain"
    };
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView android:text="AutoCompleteTextView Sample" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <AutoCompleteTextView
        android:id="@+id/auto_complete_text_view"
        android:layout_height="wrap_content"
        android:layout_width="200dp"
        />
</LinearLayout>

すると、こんな感じ。

f:id:woshidan:20151108212412p:plain

AutoCompleteTextView.Validatorを追加

国名の最初の1文字があっているかを判定する、といった簡単なValidatorを追加し、 バリデーションが通らなかったら入力されたテキストを消去し、"Wrong Text"と書かれたToastを表示する処理を書いてみた。

ポイントは、バリデーションしたいタイミングでAutoCompleteTextView#performValidation()を呼び出すこと。

public class MainActivity extends AppCompatActivity {
    private boolean mValidateResult = false;
    private String pattern = "^[BFIGS].+";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
        final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_text_view);
        textView.setAdapter(adapter);

        textView.setValidator(new AutoCompleteTextView.Validator() {
            @Override
            public boolean isValid(CharSequence text) {
                if(text.toString().matches(pattern)) {
                    mValidateResult = true;
                } else {
                    mValidateResult = false;
                }
                return mValidateResult;
            }

            @Override
            public CharSequence fixText(CharSequence invalidText) {
                return "";
            }
        });

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.performValidation();
                if (mValidateResult) {
                    Toast.makeText(MainActivity.this, "Correct Text", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "Wrong Text", Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    private static final String[] COUNTRIES = new String[] {
            "Belgium", "France", "Italy", "Germany", "Spain"
    };

こんな感じというスクショ

f:id:woshidan:20151108212401p:plain f:id:woshidan:20151108212352p:plain

なお、AutoCompleteTextView#performCompletion()だと保管用のViewをクリックさせずとも補完処理を行わせます。