Android:如何验证EditText输入?


169

我需要对一系列EditText进行表单输入验证。我使用OnFocusChangeListeners在用户键入每个用户名后触发验证,但是对于最后一个EditText,它的行为并不理想。

如果在键入最终的EditText时单击“完成”按钮,则InputMethod将断开连接,但从技术上讲,永远不会将注意力集中在EditText上(因此永远不会进行验证)。

最好的解决方案是什么?

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


1
您是否真的需要在用户键入的同时验证EditText输入?用户单击“完成”按钮后,为什么不只是验证EditText?
克里斯蒂安

这正是我想要的:当用户单击“完成”按钮时要验证文本(“完成”按钮是指QWERTY InputManager上的“完成”按钮...不是表单的提交按钮)。除了单击“完成”按钮时,焦点停留在表单中的最后一个元素上,并且从未触发我的验证方法。希望我的措辞清楚...
Stefan

@Cristian的解决方案正是我正在寻找的解决方案,可以在这里找到:stackoverflow.com/questions/43013812/…–
LampPost

@Cristian即将有点晚了,但我正在寻找一个解决方案,其中的EditText的是验证,而该人是打字。我有一个“登录/注册”表单,我只想在表单数据有效时才显示“提交”按钮。
Zonker.in.Geneva

Answers:


154

你为什么不使用TextWatcher

由于您有许多EditText需要验证的方框,因此我认为以下内容适合您:

  1. 您的活动实现了android.text.TextWatcher界面
  2. 您将TextChanged侦听器添加到您的EditText框中
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

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

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


3
看起来正是我所需要的。还没有听说过TextWatcher(SDK / API的新功能),但是我将对其进行测试,看看它是否能够按照我认为的方式运行。谢谢(你的)信息!
Stefan 2010年

1
别客气!:)既然您正在验证它,您可以分享如何将验证失败通知用户吗?我目前正在寻找相同的最佳方法。
尼克斯,2010年

Nikhil Patil,我只是使用Toast让用户知道他们做错了什么。是否有某些原因对您的情况无效?
叶夫根尼·辛金

5
当然,Toast是Android上的自然方法。但是,当我们有相当数量的在屏幕上的元素需要验证,祝酒词似乎不是正确的选择。(恕我直言,这将激怒用户),我一直在TextView.setError()(实验developer.android.com / reference / android / widget /…
Niks 2010年

1
尽管对TextWatcher的支持不佳,但它的工作原理还是不错的!
Tivie

125

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 2014年

1
@fullmeriffic最有可能您没有初始化EditText。确保您addTextChangedListener从视图中解析了Edittext后正在打电话
Ghostli,2015年

1
@StephaneEybert这是一个匿名课程
Christopher Perry

2
实践中的接口隔离原则
Maciej Beimcik,

92

如果您想在发生错误时获得良好的验证弹出窗口和图像,则可以使用我在此描述setErrorEditText类方法

setError用法的屏幕截图,摘自链接文章的作者Donn Felker


您如何获得一个TextWatcher来访问两个 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 '16

1
它已被@Length注释替换。
拉古纳斯·贾瓦哈尔(Ragunath Jawahar)

@RagunathJawahar我已经指出,如果您验证传入的数据(即联系人),则验证将不起作用,因此我试图验证来自Intent-> Contacts的电子邮件,但是一旦我专注于EditText并添加/删除任何文本,然后验证因为在TextChange上也调用了验证功能,所以当我们从Contact接收数据时,也会调用validate()。
罗纳·梅塔

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

如何与空间一起使用,并限制彼此之间没有两个空间?
chiru 2014年

10

更新的方法-TextInputLayout:

Google最近启动了设计支持库,其中有一个名为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>

步骤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

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

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

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


1
这对于输入时可以验证的内容(字母数字输入)是一个不错的解决方案,但是对于仅在用户完成输入(电子邮件地址)输入后才需要验证的内容无效。
2011年

您将如何触发该吐司?该过滤器可防止任何文本监视程序做出反应...也许是使用onKeyListener?
跨度

我从filter()方法(在InputFilter类中)通过IF条件触发了Toast。
莫伊塞斯

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验证器

    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:用于自定义regexp
  • numeric:仅用于数字字段
  • alpha:仅用于alpha字段
  • alphaNumeric:你猜怎么着?
  • personName:检查输入的文本是人物的姓还是名。
  • personFullName:检查输入的值是否为完整的全名。
  • email:检查该字段是否为有效的电子邮件
  • creditCard:使用Luhn算法检查字段是否包含有效的信用卡
  • phone:检查字段中是否包含有效的电话号码
  • domainName:检查字段是否包含有效的域名(始终通过API级别<8的测试)
  • ipAddress:检查该字段是否包含有效的IP地址
  • webUrl:检查字段是否包含有效的url(始终通过API Level <8中的测试)
  • date:检查字段是否为有效的日期/日期时间格式(如果设置了customFormat,则使用customFormat检查)
  • nocheck:除了字段为空之外,它不检查其他任何内容。

2

在main.xml文件中

您可以放置​​以下属性,以验证在编辑文本中仅接受字母字符。

做这个 :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

您可以通过在用户按下键盘上的“完成”按钮时进行聆听来获得所需的行为,还可以在我的文章“ Android表单验证-正确的方式”中查看有关使用EditText的其他提示。

样例代码:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.