* 描述:监听输入框输入的字符数 * 要注意: * 1、一个汉字算2个字符; * 2、截取显示输入内容后注意光标位置; * 3、如还能再输入一个字符,如果数的是汉字,要加以处理,以及光标重定位问题
在android 开发中,经常会遇到要求输入框内输入的文本内容限制10个汉字或20个字母的要求。之前也在网上看了很多解决方案,效果都不是很好,大多数都是直接取字符串的length()作为限定的判断依据,这个思路是非常不对的,单纯的用String.length(),去判断字符串的长度,字母和汉字的长度一样,因此我们要换一个思路去想。
根据“10个汉字或20个字母的要求”,我们可以看出,这里的汉字和字母的长度关系比值是1:2的关系,因此我们要对字符串进行编码,这个编码就是要实现这个汉字和字母1:2的比值关系,这里我们用GB2312编码,不同的编码格式,比值关系不一样,这里大家要注意!!!
public class WatcherTextUtil implements TextWatcher {
private int maxLen = 0;
private EditText editText = null;
//输入筛选条件
private String regex;
public WatcherTextUtil(int maxLen, EditText editText) {
this.maxLen = maxLen;
this.editText = editText;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
try {
// TODO Auto-generated method stub
Editable editable = editText.getText();
String content = editText.getText().toString();
byte[] bt = content.getBytes("gb2312");
if (bt.length > maxLen) {
LogUtils.d("输入字符数超过限制");
int selEndIndex = Selection.getSelectionEnd(editable);
String str = editable.toString();
byte[] bt2 = str.getBytes("gb2312");
byte[] bt3 = subBytes(bt2, 0, maxLen);
String newStrs = gbToString(bt3);
String temp = String.valueOf(newStrs.charAt(newStrs.length() - 1));
/***对最后一个字符的输入判断(正则表达式可自行修改适配):如果是汉字,将截取的一半数字字符舍去;如果是字母或数字,则保留***/
boolean flag = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(temp).matches();//汉字
boolean flag2 = (Pattern.compile("[a-zA-Z]").matcher(temp).matches()) || (Pattern.compile("[0-9]*").matcher(temp).matches());//字母或数字
if (!flag && !flag2) {
String newStrs2 = newStrs.substring(0, newStrs.length() - 1);
editText.setText(newStrs2);
} else {
editText.setText(newStrs);
}
editable = editText.getText();
// 新字符串的长度
int newLen = editable.length();
// 旧光标位置超过字符串长度
if (selEndIndex >= newLen) {
selEndIndex = editable.length();
}
//设置新光标所在的位置
Selection.setSelection(editable, selEndIndex);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void afterTextChanged(Editable editable) {
}
/**
* 将超过的字符串截取,当然,这里一定要先编码后在截取,而且是byte[]数组截取
*/
private byte[] subBytes(byte[] src, int begin, int count) {
byte[] bs = new byte[count];
System.arraycopy(src, begin, bs, 0, count);
return bs;
}
/**
* 截取好后,当然也要把byte数组里的内容转成字符串形式展现
*
*/
private String gbToString(byte[] data) {
String str = null;
try {
str = new String(data, "gb2312");
} catch (UnsupportedEncodingException e) {
}
return str;
}
}
类中直接使用:
//控制输入的字符总数 mEd_role_id.addTextChangedListener(new WatcherTextUtil(12, mEd_role_id));
2、限制输入框只能输入中文、英文、数字
mEd_role_id.setFilters(new InputFilter[]{
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!Character.isLetterOrDigit(source.charAt(i))) {
return "";
}
}
return null;
}
}
});