Android:如何验证EditText输入?

Ste*_*fan 165 android android-edittext

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

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

什么是最好的解决方案?

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

Nik*_*hil 151

你为什么不用TextWatcher

由于您有许多EditText盒子需要验证,我认为以下内容适合您:

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

Editable s并没有真正帮助找到哪个EditText框的文本被更改.但是你可以直接检查EditText框的内容

String txt1String = txt1.getText().toString();
// Validate txt1String
Run Code Online (Sandbox Code Playgroud)

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

编辑:有关更清洁的方法,请参阅下面的克里斯托弗佩里的答案.

  • 当然,Toast是android上的一种自然方式.但是当我们在屏幕上有相当数量的元素需要验证时,敬酒似乎不是正确的选择.(恕我直言,这会让用户烦恼)我一直在试验TextView.setError()(http://开发人员) .android.com /参考/机器人/插件/ TextView.html#SETERROR(java.lang.CharSequence中) (5认同)
  • 这看起来就像我需要的那样.没有听说过TextWatcher(SDK/API的新手),但我会测试它,看它是否像我想象的那样.谢谢(你的)信息! (3认同)

Chr*_*rry 119

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 */ }
}
Run Code Online (Sandbox Code Playgroud)

只需像这样使用它:

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

  • @fremmedehenvendelser:每个`EditText` IS-A`TextView` (4认同)
  • 令人敬畏的抽象和抽象类的使用 (2认同)
  • 实践中的接口隔离原则 (2认同)

Don*_*ker 89

如果您在发生错误时需要很好的验证弹出窗口和图像,您可以使用我在此处描述setErrorEditText类的方法

截取链接帖子的作者Donn Felker使用的setError的截图


Rag*_*har 24

为了减少验证逻辑的冗长,我为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;
Run Code Online (Sandbox Code Playgroud)

该库是可扩展的,您可以通过扩展Rule类来编写自己的规则.


Dan*_*son 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}); 
Run Code Online (Sandbox Code Playgroud)


Par*_*ani 9

更新的方法 - TextInputLayout:

谷歌最近推出了设计支持库,有一个名为TextInputLayout的组件,它支持通过setErrorEnabled(boolean)和显示错误setError(CharSequence).

如何使用它?

第1步:使用TextInputLayout包装EditText:

  <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>
Run Code Online (Sandbox Code Playgroud)

第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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Moi*_*sés 7

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

这是一个简单的例子: 如何使用InputFilter来限制Android中EditText中的字符?

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


And*_*ega 7

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

目前,我写的, 原生支持通过XML属性的验证方法是:

  1. α
  2. 字母数字
  3. 数字
  4. 通用正则表达式
  5. 字符串空虚

你可以在这里查看

希望你喜欢它 :)


use*_*821 6

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

    <EditText
        android:id="@+id/x" 
        android:background="@android:drawable/editbox_background" 
        android:gravity="right" 
        android:inputType="numberSigned|numberDecimal" 
    />
Run Code Online (Sandbox Code Playgroud)

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


Abs*_*Abs 5

这看起来很有前途,而且正是博士为我订购的内容:

EditText验证器

    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.
    }
}
Run Code Online (Sandbox Code Playgroud)

自定义验证器以及内置的这些:

  • regexp:用于自定义正则表达式
  • numeric:仅用于数字字段
  • alpha:仅限alpha字段
  • alphaNumeric:猜怎么着?
  • personName:检查输入的文本是人姓或姓.
  • personFullName:检查输入的值是否为完整的全名.
  • 电子邮件:检查该字段是否为有效的电子邮件
  • creditCard:使用Luhn算法检查该字段是否包含有效的信用卡
  • 电话:检查该字段是否包含有效的电话号码
  • domainName:检查该字段是否包含有效的域名(始终通过API级别<8的测试)
  • ipAddress:检查该字段是否包含有效的IP地址
  • webUrl:检查该字段是否包含有效URL(始终通过API级别<8的测试)
  • date:检查该字段是否为有效的日期/日期时间格式(如果设置了customFormat,则使用customFormat进行检查)
  • nocheck:除了田野的空虚之外,它不会检查任何东西.