1. 需求
产品经理要求EditText输入名字限制:
- 不能有除“空格,下划线,字母,数字,中文”的其他字符。
- 不能超过10个字符。
- 名字第一个字符不能为空格。
- 输入错误时,要实时检查提示并将非法字符替换为空字符。
2. 解决方案
2.1 解决思路分析
- 使用正则表达式匹配字符输入是否符合要求。
- 使用TextWatcher自定义afterTextChanged方法,每次检查完成替换。
- 注意避免循环替换
2.2 解决代码实现
TextWatcher自定义实现如下:
public class LimitTextWatcher implements TextWatcher {
private int maxLen = 0;
private EditText editText = null;
private String regex;
private String DEFAULT_REGEX = "[^ _a-zA-Z0-9\u4E00-\u9FA5]|^ .* *$";//匹配不含有_ 'a-zA-Z0-9\u4E00-\u9FA5的字符串或者开头带空格的字符串
public LimitTextWatcher(int maxLen, EditText editText) {
this.maxLen = maxLen;
this.editText = editText;
this.regex = DEFAULT_REGEX_ZH;
}
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String str = arg0.toString();
String inputStr = clearLimitStr(regex, str);//修正已输入字符
if (!str.equals(inputStr)) {//只有修正的,才做修改
editText.removeTextChangedListener(this); //去注册,再添加,为了避免循环修正判断
arg0.clear();
arg0.append(inputStr);
editText.addTextChangedListener(this);
}
processLongText();//处理字符串长度
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
private void processLongText() {
Editable editable = editText.getText();
int len = editable.length();
if (len > maxLen) {
String str = editable.toString();
editText.setText(str.substring(0, maxLen));
editable = editText.getText();
Selection.setSelection(editable, editable.length());
//showText(getString(R.string.no_more_than_eight_char)); 提示超长
}
}
private String clearLimitStr(String regex, String str) {
Matcher m = Pattern.compile(regex).matcher(str);
if (m.find()) {
showText(getString(R.string.regex_name));
}
return str.replaceAll(regex, "");
}
}
使用方法如下:
nameEditText.addTextChangedListener(new LimitTextWatcher(10, nameEditText));//nameEditText对象注册监听