一般我们在限制用户输入的时候,都是要等到用户在EditText里面输入了文本后,点击某个按钮,再去校验用户的输入是否符合规范。
接下来我介绍个新方法,可以在用户输入不规范的字符后,还没在EditText里显示出来时,就把用户的错误输入给忽略掉,不显示在EditText中,只有当用户输入了符合规范的字符时才能在EditText中显示出来。
这里需要使用到正则表达式和TextWatcher接口。
对TextWatcher不是很了解的同学看我的这篇博客:http://blog.csdn.net/zhuwentao2150/article/details/51546773
主要思路
当用户输入时,使用TextWatcher对用户的输入进行抓取,在文本还没有显示到界面之前,使用正则表达式作为判定条件,判断用户的输入是否符合标准,不符合则不显示在EditText中。
具体实现
ExamineTextWatcher实现了TextWatcher接口,在里面对用户输入的字符进行抓取,并调用校验方法
/**
* 用户输入验证器
* <p/>
* Created by zhuwentao on 2016-08-04.
*/
public class ExamineTextWatcher implements TextWatcher {
private static final String TAG = "ExamineTextWatcher";
/**
* 帐号
*/
public static final int TYPE_ACCOUNT = 1;
/**
* 金额
*/
public static final int TYPE_MONEY = 2;
/**
* 输入框
*/
private EditText mEditText;
/**
* 验证类型
*/
private int examineType;
/**
* 输入前的文本内容
*/
private String beforeText;
/**
* 构造器
*
* @param type 验证类型
* @param editText 输入框
*/
public ExamineTextWatcher(int type, EditText editText) {
this.examineType = type;
this.mEditText = editText;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// 输入前的字符
beforeText = s.toString();
Log.d(TAG, "beforeText =>>>" + beforeText );
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// 输入后的字符
String afterText = s.toString();
Log.d(TAG, "afterText =>>>" + afterText);
boolean isValid = true;
if (!TextUtils.isEmpty(afterText)) {
switch (examineType) {
case TYPE_ACCOUNT:
isValid = ValidateUtil.isAccount(afterText);
break;
case TYPE_MONEY:
isValid = ValidateUtil.isMoney(afterText);
break;
}
if (!isValid) {
// 用户现在输入的字符数减去之前输入的字符数,等于新增的字符数
int differ = afterText.length() - beforeText.length();
// 如果用户的输入不符合规范,则显示之前输入的文本
mEditText.setText(beforeText);
// 光标移动到文本末尾
mEditText.setSelection(afterText.length() - differ);
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
}
新建一个工具类ValidateUtil,使用正则表达式对用户输入的字符进行匹配
/**
* 验证工具
*
* Created by zhuwentao on 2016-08-04.
*/
public class ValidateUtil {
private ValidateUtil() {
// 防止被实例化
}
/**
* 字符串是否符合正则表达式的规则
*
* @param text 匹配文本
* @param format 匹配规则
* @return true 匹配成功 flase 匹配失败
*/
private static boolean isMatches(String text, String format) {
Pattern pattern = Pattern.compile(format);
Matcher m = pattern.matcher(text);
return m.matches();
}
/**
* 匹配帐号类型是否正确(只能输入大小写字母和数字,最大不超过20个字符)
*
* @param str 帐号
* @return true= 符合 false=不符合
*/
public static boolean isAccount(String str) {
String format = "[a-zA-Z0-9]{0,20}";
return isMatches(str, format);
}
/**
* 匹配金额是否符合要求(99999999.99)
*
* @param money 金额字符串
* @return true= 符合 false=不符合
*/
public static boolean isMoney(String money) {
String regex = "(^[1-9][0-9]{0,7}(\\.[0-9]{0,2})?)|(^0(\\.[0-9]{0,2})?)";
return isMatches(money, regex);
}
}
通过以上两个类就可以对用户的输入进行实时限制了。
使用方法很简单,给需要限制的EditText添加addTextChangedListener()方法,传入ExamineTextWatcher对象
mEditText.addTextChangedListener(new ExamineTextWatcher(ExamineTextWatcher.TYPE_ACCOUNT, mEditText));
需要添加其它限制条件时,在ValidateUtil类里添加限制条件,然后在ExamineTextWatcher类里配置好相应的验证类型标识,最后在onTextChanged()方法中调用对应的验证条件。
Demo源码:传送门