Android:EditText入力を検証するにはどうすればよいですか?


169

一連のEditTextでフォーム入力検証を行う必要があります。OnFocusChangeListenersを使用して、ユーザーがそれぞれに入力した後に検証をトリガーしていますが、これは最後のEditTextに対して希望どおりに動作しません。

最終的なEditTextに入力しているときに「Done」ボタンをクリックすると、InputMethodは切断されますが、技術的にフォーカスがEditTextに失われることはありません(したがって検証は行われません)。

最良の解決策は何ですか?

フォーカスが変更されたときではなく、InputMethodが各EditTextからバインド解除されたときを監視する必要がありますか?もしそうなら、どうですか?


1
ユーザーが入力すると同時にEditText入力を検証する必要がありますか?ユーザーが[完了]ボタンをクリックしたら、EditTextを検証しませんか?
クリスティアン

それがまさに私が望んでいることです。ユーザーが[完了]ボタンをクリックしたときにテキストを検証するには([完了]ボタンとは、QWERTY InputManagerの[完了]ボタンを意味します...フォームの送信ボタンではありません)。ただし、[完了]ボタンを押すと、フォーカスはフォームの最後の要素に留まり、検証メソッドがトリガーされることはありません。私の言い回しが明確であることを願っています...
ステファン、

@Cristianのソリューションは、まさに私が探していたのであり、ここで発見された:stackoverflow.com/questions/43013812/...
街灯を

@Cristian少し遅れますが、入力中に EditTextが検証されるソリューションを探しています。ログイン/登録フォームがあり、フォームデータが有効な場合にのみ [送信]ボタンを表示したい。
Zonker.in.Geneva

回答:


154

使ってみませんTextWatcherか?

EditText検証するボックスの数が多いので、次のものが適していると思います。

  1. あなたの活動はandroid.text.TextWatcherインターフェースを実装します
  2. EditChangeボックスにTextChangedリスナーを追加します
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
  1. オーバーライドされたメソッドのうち、afterTextChanged(Editable s)次のようにメソッドを使用できます
@Override
public void afterTextChanged(Editable s) {
    // validation code goes here
}

Editable s実際のEditTextボックスのテキストが変更されているかを見つけるためには役立ちません。しかし、次のようにEditTextボックスの内容を直接確認できます。

String txt1String = txt1.getText().toString();
// Validate txt1String

同じ方法で。私は私が明確であることを望み、私がそうであるならば、それは助けになります!:)

編集:よりクリーンなアプローチについては、以下のクリストファーペリーの回答を参照してください。


3
それはまさに私が必要としているもののように見えます。TextWatcher(SDK / APIの新機能)については聞いていませんが、テストして、思ったとおりに動作するかどうかを確認します。情報をありがとう!
ステファン、

1
どういたしまして!:)それを検証しているところで、検証の失敗をユーザーにどのように通知するつもりですか?私は現在、同じための最良の方法を探しています。
Niks

Nikhil Patil、私はToastを使用して、ユーザーが何か間違ったことをしたことをユーザーに知らせています。あなたのケースでそれが効果的でない理由はありますか?
Yevgeny Simkin、2010年

5
もちろん、トーストはAndroidで自然な方法です。しかし、検証が必要な画面上の要素がかなりある場合、トーストは正しい選択ではないようです(IMHO、ユーザーを困らせるでしょう)TextView.setError()(developer.android.com / reference / android / widget /…
Niks

1
TextWatcherのサポートは貧弱ですが、動作します...ちょっと!
Tivieは

126

TextWatcherは私の好みに少し冗長なので、飲み込みやすいものを作りました。

public abstract class TextValidator implements TextWatcher {
    private final TextView textView;

    public TextValidator(TextView textView) {
        this.textView = textView;
    }

    public abstract void validate(TextView textView, String text);

    @Override
    final public void afterTextChanged(Editable s) {
        String text = textView.getText().toString();
        validate(textView, text);
    }

    @Override
    final public void beforeTextChanged(CharSequence s, int start, int count, int after) { /* Don't care */ }

    @Override
    final public void onTextChanged(CharSequence s, int start, int before, int count) { /* Don't care */ }
}

次のように使用してください:

editText.addTextChangedListener(new TextValidator(editText) {
    @Override public void validate(TextView textView, String text) {
       /* Validation code here */
    }
});

4
@fremmedehenvendelser:すべてのEditTextIS-ATextView
Niks

2
素晴らしい抽象化と抽象クラスの使用
Saher Ahwal

1
@fullmerifficおそらくEditTextを初期化していません。addTextChangedListenerビューからedittextを解決した後、必ず電話をかけてください
Ghostli


2
インターフェース分離の原則
Maciej Beimcik

92

エラーが発生したときに素晴らしい検証ポップアップと画像が必要な場合setErrorは、ここでEditText説明するようにクラスのメソッドを使用できます

リンクされた投稿の作成者であるDonn FelkerによるsetErrorの使用のスクリーンショット


TextWatcherで2つの EditText にアクセスするにはどうすればよいですか?TextWatcherをに正常に追加しましたpasswordConfirmTextFieldが、他のを参照して、passwordTextFieldそれらを比較できるようにする必要があります。助言がありますか?
Zonker.in.Geneva

26

検証ロジックの冗長性を減らすために、Android用のライブラリを作成しました。これは、アノテーションと組み込みルールを使用して、日々の検証のほとんどを処理します。以下のような制約がありますが@TextRule@NumberRule@Required@Regex@Email@IpAddress@Password、など、

これらの注釈をUIウィジェット参照に追加して、検証を実行できます。また、検証を非同期で実行できるため、リモートサーバーからの一意のユーザー名を確認する場合などに最適です。

注釈の使用方法については、プロジェクトのホームページに例があります。検証用のカスタムルールを作成する方法のサンプルコードを記述した関連するブログ投稿を読むこともできます。

これは、ライブラリの使用法を表す簡単な例です。

@Required(order = 1)
@Email(order = 2)
private EditText emailEditText;

@Password(order = 3)
@TextRule(order = 4, minLength = 6, message = "Enter at least 6 characters.")
private EditText passwordEditText;

@ConfirmPassword(order = 5)
private EditText confirmPasswordEditText;

@Checked(order = 6, message = "You must agree to the terms.")
private CheckBox iAgreeCheckBox;

ライブラリは拡張可能ですRule。クラスを拡張することにより、独自のルールを作成できます。


このライブラリは魅力のように機能します。しかし、@ TextRuleアノテーションはバージョン2.0.3から削除されましたか?
LTroya

1
@Lengthアノテーションに置き換えられました。
Ragunath Jawahar

@RagunathJawahar受信データ、つまり連絡先を検証すると検証が機能しないことを指摘したので、インテント->連絡先から送信された電子メールを検証しようとしていますが、EditTextに焦点を当ててテキストを追加/削除してから検証しますTextChangeで検証が呼び出され、Contactからデータを受信したときにvalidate()も呼び出されるので、機能します。
Ronak Mehta 2016

11

これはここからの良い解決策でし

InputFilter filter= new InputFilter() { 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
        for (int i = start; i < end; i++) { 
            String checkMe = String.valueOf(source.charAt(i));

            Pattern pattern = Pattern.compile("[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789_]*");
            Matcher matcher = pattern.matcher(checkMe);
            boolean valid = matcher.matches();
            if(!valid){
                Log.d("", "invalid");
                return "";
            }
        } 
        return null; 
    } 
};

edit.setFilters(new InputFilter[]{filter}); 

スペースと一緒に使用し、隣同士の2つのスペースを制限しないようにするにはどうすればよいですか?
チル、2014

10

更新されたアプローチ-TextInputLayout:

Googleは最近デザインサポートライブラリをリリースしました。TextInputLayoutと呼ばれるコンポーネントが1つsetErrorEnabled(boolean)あり、およびを介したエラーの表示をサポートしていますsetError(CharSequence)

どうやって使うのですか?

ステップ1:EditTextをTextInputLayoutでラップします。

  <android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/layoutUserName">

    <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="hint"
      android:id="@+id/editText1" />

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

ステップ2:入力を検証する

// validating input on a button click
public void btnValidateInputClick(View view) {

    final TextInputLayout layoutUserName = (TextInputLayout) findViewById(R.id.layoutUserName);
    String strUsername = layoutLastName.getEditText().getText().toString();

    if(!TextUtils.isEmpty(strLastName)) {
        Snackbar.make(view, strUsername, Snackbar.LENGTH_SHORT).show();
        layoutUserName.setErrorEnabled(false);
    } else {
        layoutUserName.setError("Input required");
        layoutUserName.setErrorEnabled(true);
    }
}

私はGithubリポジトリでサンプルを作成しました。必要に応じてサンプルをチェックアウトしてください!


ベストアンサーですが、使用する必要がありましたcom.google.android.material.textfield.TextInputLayout材料の変更に注意してください)。この答えからそれを得た:stackoverflow.com/a/56753953/900394
Alaa M.

8

EditTextを拡張するクラスを作成しました。これは、いくつかの検証メソッドをネイティブでサポートし、実際には非常に柔軟です。

現在、私が書いているように、 xml属性の検証メソッドを通じてネイティブにサポートされています

  1. アルファ
  2. 英数字
  3. 数値
  4. 一般的な正規表現
  5. 文字列の空

こちらでチェックできます

楽しんでください :)


7

Androidでのテキスト入力の検証には、InputFilterがより適切であると思います。

簡単な例を次に示します 。InputFilterを使用して、AndroidのEditTextの文字を制限するにはどうすればよいですか。

トーストを追加して、制限についてユーザーにフィードバックできます。また、android:inputTypeタグも確認してください。


1
これは、入力時に検証できるもの(英数字の入力)に適したソリューションですが、ユーザーが入力(電子メールアドレス)を入力した後にのみ検証する必要があるものには機能しません。
Peter Ajtai、2011

どのようにトーストをトリガーしますか?フィルターは、テキストウォッチャーが反応するのを防ぎます...おそらくonKeyListenerを使用しますか?
スパン

そのToastを、(InputFilterクラスの)filter()メソッドからのIF条件でトリガーしました。
モイセス

6

私は、フィールド間検証ではなくフィールド内検証を行う必要がありました。私の値が、ある場合では符号なし浮動小数点値であり、別の場合では符号付き浮動小数点値であることをテストするためです。これが私にとってうまくいくようです:

    <EditText
        android:id="@+id/x" 
        android:background="@android:drawable/editbox_background" 
        android:gravity="right" 
        android:inputType="numberSigned|numberDecimal" 
    />

「numberSigned | numberDecimal」内にはスペースを入れないでください。例:「numberSigned | numberDecimal」は機能しません。理由はわかりません。


5

これは本当に有望に見え、ドキュメントが私に注文したものです:

EditText Validator

    public void onClickNext(View v) {
    FormEditText[] allFields    = { etFirstname, etLastname, etAddress, etZipcode, etCity };
    
    
    boolean allValid = true;
    for (FormEditText field: allFields) {
        allValid = field.testValidity() && allValid;
    }
    
    if (allValid) {
        // YAY
    } else {
        // EditText are going to appear with an exclamation mark and an explicative message.
    }
}

カスタムバリデーターに加えてこれらの組み込み:

  • regexp:カスタム正規表現用
  • numeric:数値フィールドのみ
  • alpha:アルファのみのフィールド用
  • alphaNumeric:何だと思う?
  • personName:入力したテキストが人物の姓か名かを確認します。
  • personFullName:入力した値が完全なフルネームかどうかを確認します。
  • email:フィールドが有効なメールであることを確認します
  • creditCardLuhnアルゴリズムを使用して、フィールドに有効なクレジットカードが含まれていることを確認します
  • phone:フィールドに有効な電話番号が含まれていることを確認します
  • domainName:フィールドに有効なドメイン名が含まれていることを確認します(常にAPIレベル<8のテストに合格します)
  • ipAddress:フィールドに有効なIPアドレスが含まれていることを確認します
  • webUrl:フィールドに有効なURLが含まれていることを確認します(常にAPIレベル<8のテストに合格します)
  • date:フィールドが有効な日付/日時形式であることを確認します(customFormatが設定されている場合は、customFormatで確認します)
  • nocheck:フィールドが空であること以外は何もチェックしません。

2

main.xmlファイル内

edittextで受け入れることができるのはアルファベット文字のみであることを検証するために、次の属性を設定できます。

これを行う :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

ユーザーがキーボードの[完了]ボタンを押したときに聞くことで、希望の動作を得ることができます。また、私の投稿でEditTextを使用するための他のヒントを確認してください 「Androidフォームの検証-正しい方法」確認してください。

サンプルコード:

mTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {                    
            validateAndSubmit();
            return true;
        }
        return false;
    }});  

0

電子メールとパスワードの検証のために

  if (isValidEmail(et_regemail.getText().toString())&&etpass1.getText().toString().length()>7){
      if (validatePassword(etpass1.getText().toString())) {
      Toast.makeText(getApplicationContext(),"Go Ahead".....
      }
      else{

       Toast.makeText(getApplicationContext(),"InvalidPassword".....
       }

}else{

 Toast.makeText(getApplicationContext(),"Invalid Email".....
}


public boolean validatePassword(final String password){
    Pattern pattern;
    Matcher matcher;
    final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[A-Z])(?=.* 
    [@#$%^&+=!])(?=\\S+$).{4,}$";
    pattern = Pattern.compile(PASSWORD_PATTERN);
    matcher = pattern.matcher(password);

    return matcher.matches();
}

public final static boolean isValidEmail(CharSequence target) {
    if (target == null)
        return false;

    return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}

-2

私はこのライブラリをAndroid用に作成しました。このライブラリでは、マテリアルデザインEditTextとEditTextLayoutを次のように簡単に検証できます。

    compile 'com.github.TeleClinic:SmartEditText:0.1.0'

その後、次のように使用できます。

<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
    android:id="@+id/passwordSmartEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:setLabel="Password"
    app:setMandatoryErrorMsg="Mandatory field"
    app:setPasswordField="true"
    app:setRegexErrorMsg="Weak password"
    app:setRegexType="MEDIUM_PASSWORD_VALIDATION" />

<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
    android:id="@+id/ageSmartEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:setLabel="Age"
    app:setMandatoryErrorMsg="Mandatory field"
    app:setRegexErrorMsg="Is that really your age :D?"
    app:setRegexString=".*\\d.*" />

次に、それが次のように有効かどうかを確認できます。

    ageSmartEditText.check()

その他の例とカスタマイズについては、リポジトリhttps://github.com/TeleClinic/SmartEditTextを確認して ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.