我需要在一系列EditTexts上进行表单输入验证。我使用OnFocusChangeListeners在用户输入每个文件后触发验证,但这不符合上一个EditText的需要。
如果在输入最终的EditText时单击“完成”按钮,则InputMethod将断开连接,但技术上焦点永远不会丢失在EditText上(因此验证永远不会发生)。
什么是最好的解决方案?
当InputMethod从每个EditText取消绑定而不是焦点更改时,我应该监视吗?如果是这样,怎么样?
答案 0 :(得分:148)
为什么不使用TextWatcher
?
由于您要验证多个EditText
框,我认为以下内容适合您:
android.text.TextWatcher
界面txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
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'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)
答案 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)
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)
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属性验证方法支持原生:
您可以查看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)
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.
}
}
答案 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