思路依据:
Java中无论是汉字还是英文字母都是用Unicode编码来表示的,一个Unicode码是16位,每字节是8位,所以一个Unicode码占至少两字节。但是英文字母比较特殊,源自于8位(1字节)的ASCII吗,于是在Unicode码仅使用了低8位(1字节)就可以表示,高8位的话不使用也无所谓。所以
char a = ‘a’;
byte b = (byte) a;
a = (char) b;
System.out.println(a);//最后输出结果还是a
但是中就不行了,中文至少占两个字节,经过上面转换会丢失高于1个字节的编码
实战
首先来看一下,TextWatcher 接口
public interface TextWatcher extends NoCopySpan {
@Override public void afterTextChanged(Editable s) {//表示最终内容
}
@Override
public void beforeTextChanged(CharSequence s, int start/*开始的位置*/, int count/*删除的内容数*/, int after/*增加的内容数量*/) {
//这里的s表示改变之前的内容,通常start和count组合,可以在s中读取本次删除的内容。而after表示增加的内容数量。
}
@Override
public void onTextChanged(CharSequence s, int start/*开始位置*/, int before/*删除内容的数量*/, int count/*新增数*/) {
//这里的s表示改变之后的内容,
}
接下来,贴出判断是不是中文让人眼前一亮的代码,当时楼主看到的时候,感到很赞~~
(char) (byte) s.charAt(index) != s.charAt(index)
这段代码什么意思呢,大家都知道 byte在java中占一个字节,char占两个字节。根据上面思路依据所知中文在java中占两个字节。而英文、中文在char中都占一个char的长度。那么byte在java中占一个字节,英文为一个字节,char两个字节,我把char转成byte,就把2个字节转成一个字节。如果是英文没问题。char转byte还等于原来的char。但是中文就有问题了。因为中文占2个字节,char转byte丢了一个字节,那么char转byte后就不等于原来的char了
####最终代码
public class BaseTextChangedListener implements TextWatcher {
/**
* 中文占2个长度,英文占一个长度
*/
protected int mMaxLength = 10;
protected int mCurrentLength = 0;
EditText mEditText;
public BaseTextChangedListener(int maxLength, EditText editText) {
this.mMaxLength = maxLength;
this.mEditText = editText;
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mEditText == null) {
return;
}
if (count != 0) {//增加了新内容,注意count和before的取值范围为>=1
for (int index = start; index < start + count; index++) {
if ((char) (byte) s.charAt(index) != s.charAt(index)) {//判断输入的是不是中文
mCurrentLength += 2;
} else {
mCurrentLength += 1;
}
if (mCurrentLength > mMaxLength) {//输入的字符长度大于最大长度
mEditText.removeTextChangedListener(this);
String leftString = s.subSequence(0, index).toString();//获取最大合法长度的内容
mEditText.setText(leftString);
mEditText.setSelection(index);
mEditText.addTextChangedListener(this);
if ((char) (byte) s.charAt(index) != s.charAt(index)) {
mCurrentLength -= 2;
} else {
mCurrentLength -= 1;
}
return;
}//end mCurrentLength > mMaxLength
}// end for
}//end count != 0
mCurrentLength = 0;
//重新计算当前的总长度
char[] chars = s.toString().toCharArray();
for (int i = 0; i < chars.length; i++) {
if ((char) (byte) chars[i] != chars[i]) {
mCurrentLength += 2;
} else {
mCurrentLength += 1;
}
}
}
@Override public void afterTextChanged(Editable s) {
}
}
注意
mEditText.removeTextChangedListener(this);//如果不remove setText会再次调用TextWatcher 造成递归
mEditText.setText(leftString);
mEditText.addTextChangedListener(this);
###思路
在onTextChanged中,我们首先判断是不是增加了内容,如果不是,直接统计最新的长度,如果是则循环遍历每个字符,并且判断每个字符是中文还是英文。如果遍历到某个字符时,长度超过了限制的大小则生成新的字符串,新的字符串为改变后的字符串裁剪到超过限制的前一个字符。