需求
- 对输入框输入字符做字符长度限制
- 汉字占两个字符,字母占一个字符
结果
- 汉字(根据字符实际占用字节获得,另含大量特殊字符)占两个字符,字母(根据字符实际占用字节获得,另含大量特殊字符)占一个字符
- 在预期不超长时正常输入,在预期超长时截取新输入字符首端最大长度拼接(词组、粘贴、复制、联想等),在已超长时无法输入
实现
/**
* EditText 字符长度限制(字母一个字符,汉字两个字符)
*
* @author gavin.xiong 2017/7/12
*/
public class LengthFilter implements InputFilter {
private final int MAX_EN; // 最大英文/数字长度 一个汉字算两个字母
public LengthFilter(int MAX_EN) {
this.MAX_EN = MAX_EN;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// 新输入的字符串为空直接不接收(删除剪切等)
if (TextUtils.isEmpty(source)) return "";
// 输入前就存在的字符长度
int destCount = getCount(dest.toString());
// 输入前就已满直接不接收
if (destCount >= MAX_EN) return "";
// 新输入的字符长度
int sourceCount = getCount(source.toString());
// 如果拼接后不超长,直接拼接
if (destCount + sourceCount <= MAX_EN) return source;
// 超长时不应该直接拒绝,应在允许范围内尽量拼接
return getByCount(source.toString(), MAX_EN - destCount);
}
/**
* 超长时根据剩余长度在字符范围内截取字符串
*/
private String getByCount(String s, int count) {
String temp = "";
int tempCount = 0;
char[] cs = s.toCharArray();
for (char c : cs) {
if (tempCount + getCount(c) <= count) {
tempCount += getCount(c);
temp += c;
} else {
break;
}
}
return temp;
}
/**
* 计算字符串长度
*/
private int getCount(String s) {
if (TextUtils.isEmpty(s)) {
return 0;
}
int count = 0;
char[] cs = s.toCharArray();
for (char c : cs) {
count += getCount(c);
}
return count;
}
/**
* 单字符占位判定
*/
private int getCount(char c) {
return String.valueOf(c).getBytes().length > 2 ? 2 : 1;
}
}
editText.setFilters(new InputFilter[]{new LengthFilter(20)});