Android:如何验证 EditText 输入?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2763022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: How can I validate EditText input?
提问by Stefan
I need to do form input validation on a series of EditTexts. I'm using OnFocusChangeListeners to trigger the validation after the user types into each one, but this doesn't behave as desired for the last EditText.
我需要对一系列 EditText 进行表单输入验证。我正在使用 OnFocusChangeListeners 在用户键入每个内容后触发验证,但这对于最后一个 EditText 的行为不符合预期。
If I click on the "Done" button while typing into the final EditText then the InputMethod is disconnected, but technically focus is never lost on the EditText (and so validation never occurs).
如果我在输入最终 EditText 时单击“完成”按钮,则 InputMethod 断开连接,但技术上的焦点永远不会丢失在 EditText 上(因此验证永远不会发生)。
What's the best solution?
最好的解决办法是什么?
Should I be monitoring when the InputMethod unbinds from each EditText rather than when focus changes? If so, how?
我应该在 InputMethod 何时从每个 EditText 解除绑定而不是在焦点发生变化时进行监控吗?如果是这样,如何?
采纳答案by Niks
Why don't you use TextWatcher
?
你为什么不使用TextWatcher
?
Since you have a number of EditText
boxes to be validated, I think the following shall suit you :
由于您有许多EditText
盒子需要验证,我认为以下内容适合您:
- Your activity implements
android.text.TextWatcher
interface - You add TextChanged listeners to you EditText boxes
- 您的活动实现
android.text.TextWatcher
接口 - 您将 TextChanged 侦听器添加到 EditText 框
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
- Of the overridden methods, you could use the
afterTextChanged(Editable s)
method as follows
- 在重写的方法中,您可以
afterTextChanged(Editable s)
按如下方式使用该方法
@Override
public void afterTextChanged(Editable s) {
// validation code goes here
}
The Editable s
doesn't really help to find which EditText box's text is being changed. But you could directly check the contents of the EditText boxes like
这Editable s
并不能真正帮助找到正在更改哪个 EditText 框的文本。但是您可以直接检查 EditText 框的内容,例如
String txt1String = txt1.getText().toString();
// Validate txt1String
in the same method. I hope I'm clear and if I am, it helps! :)
用同样的方法。我希望我很清楚,如果我清楚,它会有所帮助!:)
EDIT:For a cleaner approach refer to Christopher Perry's answerbelow.
编辑:有关更清洁的方法,请参阅下面的Christopher Perry 的回答。
回答by Christopher Perry
TextWatcher is a bit verbose for my taste, so I made something a bit easier to swallow:
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 */ }
}
Just use it like this:
只需像这样使用它:
editText.addTextChangedListener(new TextValidator(editText) {
@Override public void validate(TextView textView, String text) {
/* Validation code here */
}
});
回答by Donn Felker
回答by Ragunath Jawahar
In order to reduce the verbosity of the validation logic I have authored a library for Android. It takes care of most of the day to day validations using Annotations and built-in rules. There are constraints such as @TextRule
, @NumberRule
, @Required
, @Regex
, @Email
, @IpAddress
, @Password
, etc.,
为了减少验证逻辑的冗长,我为 Android编写了一个库。它使用注释和内置规则处理大部分日常验证。存在诸如约束@TextRule
,@NumberRule
,@Required
,@Regex
,@Email
,@IpAddress
,@Password
,等,
You can add these annotations to your UI widget references and perform validations. It also allows you to perform validations asynchronously which is ideal for situations such as checking for unique username from a remote server.
您可以将这些注释添加到您的 UI 小部件引用中并执行验证。它还允许您异步执行验证,这非常适用于从远程服务器检查唯一用户名等情况。
There is a example on the project home pageon how to use annotations. You can also read the associated blog postwhere I have written sample codes on how to write custom rules for validations.
项目主页上有一个关于如何使用注释的示例。您还可以阅读相关的博客文章,其中我编写了有关如何编写自定义验证规则的示例代码。
Here is a simple example that depicts the usage of the library.
这是一个简单的例子,描述了库的用法。
@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;
The library is extendable, you can write your own rules by extending the Rule
class.
该库是可扩展的,您可以通过扩展Rule
类来编写自己的规则。
回答by Daniel Magnusson
This was nice solution from 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});
回答by Paresh Mayani
Updated approach - TextInputLayout:
更新方法 - TextInputLayout:
Google has recently launched design support library and there is one component called TextInputLayoutand it supports showing an error via setErrorEnabled(boolean)
and setError(CharSequence)
.
Google 最近推出了设计支持库,并且有一个名为TextInputLayout 的组件,它支持通过setErrorEnabled(boolean)
和显示错误setError(CharSequence)
。
How to use it?
如何使用它?
Step 1: Wrap your EditText with TextInputLayout:
第 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>
Step 2: Validate input
第 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);
}
}
I have created an example over my Github repository, checkout the example if you wish to!
我在我的Github 存储库上创建了一个示例,如果您愿意,请查看示例!
回答by Andrea Baccega
I wrote a class that extends EditText which supports natively some validation methods and is actually very flexible.
我编写了一个扩展 EditText 的类,它本身支持一些验证方法,而且实际上非常灵活。
Current, as I write, nativelysupported through xml attributesvalidation methods are:
目前,正如我所写, 通过xml 属性验证方法本机支持的是:
- alpha
- alpha numeric
- numeric
- generic regexp
- string emptyness
- α
- 字母数字
- 数字
- 通用正则表达式
- 字符串空性
You can check it out here
你可以在这里查看
Hope you enjoy it :)
希望你喜欢它 :)
回答by Moisés
I find InputFilter to be more appropriate to validate text inputs on android.
我发现 InputFilter 更适合验证 android 上的文本输入。
Here's a simple example: How do I use InputFilter to limit characters in an EditText in Android?
这是一个简单的示例: 如何使用 InputFilter 限制 Android 中 EditText 中的字符?
You could add a Toast to feedback the user about your restrictions. Also check the android:inputType tag out.
您可以添加 Toast 来向用户反馈您的限制。还要检查 android:inputType 标签。
回答by user405821
I needed to do intra-field validation and not inter-field validation to test that my values were unsigned floating point values in one case and signed floating point values in another. Here's what seems to work for me:
我需要进行字段内验证而不是字段间验证,以测试我的值在一种情况下是无符号浮点值,而在另一种情况下是有符号浮点值。这似乎对我有用:
<EditText
android:id="@+id/x"
android:background="@android:drawable/editbox_background"
android:gravity="right"
android:inputType="numberSigned|numberDecimal"
/>
Note, you must not have any spaces inside "numberSigned|numberDecimal". For example: "numberSigned | numberDecimal" won't work. I'm not sure why.
请注意,“numberSigned|numberDecimal”中不能有任何空格。例如:“numberSigned | numberDecimal”将不起作用。我不知道为什么。
回答by Abs
This looks really promising and just what the doc ordered for me:
这看起来非常有希望,而且正是医生为我订购的:
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.
}
}
custom validators plus these built in:
自定义验证器加上这些内置:
- regexp: for custom regexp
- numeric: for an only numeric field
- alpha: for an alpha only field
- alphaNumeric: guess what?
- personName: checks if the entered text is a person first or last name.
- personFullName: checks if the entered value is a complete full name.
- email: checks that the field is a valid email
- creditCard: checks that the field contains a valid credit card using Luhn Algorithm
- phone: checks that the field contains a valid phone number
- domainName: checks that field contains a valid domain name ( always passes the test in API Level < 8 )
- ipAddress: checks that the field contains a valid ip address
- webUrl: checks that the field contains a valid url ( always passes the test in API Level < 8 )
- date: checks that the field is a valid date/datetime format ( if customFormat is set, checks with customFormat )
- nocheck: It does not check anything except the emptyness of the field.
- regexp: 用于自定义正则表达式
- numeric: 仅用于数字字段
- alpha: 对于只有 alpha 的字段
- alphaNumeric: 你猜怎么着?
- personName:检查输入的文本是人名还是姓氏。
- personFullName:检查输入的值是否是完整的全名。
- email: 检查该字段是否是有效的电子邮件
- creditCard:使用Luhn 算法检查该字段是否包含有效的信用卡
- phone: 检查该字段是否包含有效的电话号码
- domainName:检查该字段包含有效域名(始终通过 API Level < 8 中的测试)
- ipAddress: 检查该字段是否包含有效的 ip 地址
- webUrl:检查该字段是否包含有效的 url(始终通过 API Level < 8 中的测试)
- date:检查该字段是否为有效的日期/日期时间格式(如果设置了 customFormat,则使用 customFormat 进行检查)
- nocheck:除了字段的空性之外,它不检查任何内容。