Android:如何验证EditText输入?

时间:2010-05-04 05:35:11

标签: android android-edittext

我需要在一系列EditTexts上进行表单输入验证。我使用OnFocusChangeListeners在用户输入每个文件后触发验证,但这不符合上一个EditText的需要。

如果在输入最终的EditText时单击“完成”按钮,则InputMethod将断开连接,但技术上焦点永远不会丢失在EditText上(因此验证永远不会发生)。

什么是最好的解决方案?

当InputMethod从每个EditText取消绑定而不是焦点更改时,我应该监视吗?如果是这样,怎么样?

14 个答案:

答案 0 :(得分:148)

为什么不使用TextWatcher

由于您要验证多个EditText框,我认为以下内容适合您:

  1. 您的活动实施android.text.TextWatcher界面
  2. 您将TextChanged侦听器添加到EditText框
  3. txt1.addTextChangedListener(this);
    txt2.addTextChangedListener(this);
    txt3.addTextChangedListener(this);
    
    1. 在重写方法中,您可以使用afterTextChanged(Editable s)方法,如下所示
    2. @Override
      public void afterTextChanged(Editable s) {
          // validation code goes here
      }
      

      Editable s并没有真正帮助查找哪个EditText框的文本正在被更改。但您可以直接检查EditText框的内容,如

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

      用同样的方法。我希望我很清楚,如果我是,它会有所帮助! :)

      编辑:有关更清洁的方法,请参阅下面的Christopher Perry's answer

答案 1 :(得分:116)

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 */
    }
});

答案 2 :(得分:87)

如果您在发生错误时需要很好的验证弹出窗口和图片,可以使用EditText类的setError方法,因为我描述了here

Screenshot of the use of setError taken from Donn Felker, the author of the linked post

答案 3 :(得分:24)

为了减少验证逻辑的详细程度,我创作了library for Android。它使用注释和内置规则来处理大多数日常验证。存在约束,例如@TextRule@NumberRule@Required@Regex@Email@IpAddress@Password等,

您可以将这些注释添加到UI小部件引用并执行验证。它还允许您异步执行验证,这对于检查远程服务器的唯一用户名等情况非常理想。

project home page上有一个关于如何使用注释的示例。您还可以阅读associated blog post,其中我编写了有关如何编写自定义验证规则的示例代码。

这是一个描述库使用情况的简单示例。

@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类来编写自己的规则。

答案 4 :(得分:11)

here

这是一个很好的解决方案
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}); 

答案 5 :(得分:9)

更新方法 - TextInputLayout:

Google最近推出了设计支持库,有一个名为TextInputLayout的组件,它支持通过setError(CharSequence) <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> 显示错误。

如何使用?

第1步:使用TextInputLayout包装EditText:

// 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);
    }
}

第2步:验证输入

[Category-1-Name] => Array      // Category-array
(
  [descripion] => 'some description here'
  [posts] => Array
    [0] => Array                  // Post-array
      (
        [0] => Post-0-name
        [1] => Post-0-url
        [2] => Post-0-text
      )

我已经在我的Github repository上创建了一个示例,如果您愿意,请查看示例!

答案 6 :(得分:7)

我发现InputFilter更适合验证android上的文本输入。

这是一个简单的例子: How do I use InputFilter to limit characters in an EditText in Android?

您可以添加Toast以向用户反馈您的限制。 还要检查android:inputType标签。

答案 7 :(得分:7)

我编写了一个扩展EditText的类,它本身支持一些验证方法,实际上非常灵活。

目前,正如我所写,通过 xml属性验证方法支持原生

  1. 阿尔法
  2. 字母数字
  3. 数字
  4. generic regexp
  5. string emptyness
  6. 您可以查看here

    希望你喜欢它:)

答案 8 :(得分:6)

我需要进行场内验证而不是场间验证,以测试我的值在一种情况下是无符号浮点值,在另一种情况下是有符号浮点值。这似乎对我有用:

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

注意,“numberSigned | numberDecimal”中不能有任何空格。例如:“numberSigned | numberDecimal”将不起作用。我不知道为什么。

答案 9 :(得分:5)

这看起来非常有前途,而且正是doc为我订购的内容:

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 :for custom regexp
  • 数字:仅限数字字段
  • alpha :仅限alpha字段
  • alphaNumeric :猜猜是什么?
  • personName :检查输入的文字是否为姓名。
  • personFullName :检查输入的值是否为完整的全名。
  • 电子邮件:检查该字段是否为有效的电子邮件
  • creditCard :使用Luhn Algorithm
  • 检查该字段是否包含有效的信用卡
  • 手机:检查该字段是否包含有效的电话号码
  • domainName :检查该字段是否包含有效的域名(始终在API级别&lt; 8中通过测试)
  • ipAddress :检查该字段是否包含有效的IP地址
  • webUrl :检查该字段是否包含有效网址(始终在API级别&lt; 8中通过测试)
  • 日期:检查该字段是否为有效的日期/日期时间格式(如果设置了customFormat,则使用customFormat进行检查)
  • nocheck :除了字段空白外,它不会检查任何内容。

答案 10 :(得分:3)

在main.xml文件中

您可以将以下属性仅用于验证字符在edittext中可以接受的字母。

这样做:

  android:entries="abcdefghijklmnopqrstuvwxyz"

答案 11 :(得分:2)

当用户点击键盘上的“完成”按钮时,您可以通过收听来获得所需的行为,还可以查看有关在我的帖子中使用EditText的其他提示"Android form validation - the right way"

示例代码:

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;
    }});  

答案 12 :(得分: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();
}

答案 13 :(得分:-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