android 中显示 EditView输入的字符数(中文 gbk 2个字符),不是字数!!
setMaxLength()和setFilter(),限制的是输入字数,而不是字符数。
下面介绍如何限制输入字符数:
输入监听:
/*
* 监听输入内容是否超出最大长度,并设置光标位置
* */class MaxLengthWatcher implements TextWatcher {
private int maxLen = 0;
private EditText editText = null;
public MaxLengthWatcher(int maxLen, EditText editText) {
this.maxLen = maxLen;
this.editText = editText;
}
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
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
Editable editable = editText.getText();
String s= editable + "";
int len = editable.length();
try {
byte a[] = s.getBytes("gbk");
len = a.length;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (len > maxLen) {
int selEndIndex = Selection.getSelectionEnd(editable);
String str = editable.toString();
D.e("str:"+str+"|len:"+len);
//截取新字符串
String newStr = StringUtil.cutString(str,30);
D.e("newStr:"+newStr+"|len:"+len);
editText.setText(newStr);
editable = editText.getText();
//新字符串的长度
int newLen = editable.length();
//旧光标位置超过字符串长度
if (selEndIndex > newLen) {
selEndIndex = editable.length();
}
//设置新光标所在的位置
Selection.setSelection(editable, selEndIndex);
}
}
}
按字符数切割中英混排字符串
public class StringUtil {
/*取中英混排 字符串中前n 个字符串 gbk 中文2位,英文1位 编码*/
public static String cutString(String target, int num) {
StringBuffer sb = new StringBuffer();
int childLength = 0;
int targetLength = target.length();
try {
for (int i = 0; i < targetLength; i++) {
String tem = target.substring(i, i + 1);
childLength += (tem.getBytes("gbk")).length;
if (childLength <= num) {
sb.append(tem);
Log.e("string","tem is "+tem+"\tlength is "+childLength+"\tsb is "+sb.toString());
} else {
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sb.toString();
}
}
最后在activity中应用:
只需一行代码哟!!
et.addTextChangedListener(new MaxLengthWatcher(30, et));
就是这么简单!完活,下班回家!!
增强代码:现在考虑 中文、英文、emoji混排的字符串,更新方法如下:
/**截取中英混排,甚至emoji混排的 字符串中前n 个字符串
* 现在又要把emoji的情况考虑进去,所有用utf-8(可变长度编码集:英文是1个字符;汉子大约是3个,复杂的是4个字符;emoji是4个字符)
* 但是不知道编码的程序设计师们只会认为 英文数字是1个字符,汉字、emoji什么的zh占2个字符
* 所以,用utf-8编码,大于1,也就是非英文数字,即算作2个字符。遂符合设计之意
*/
public static String cutString(String target, int num) {
StringBuffer sb = new StringBuffer();
int childLength = 0;
int targetLength = target.length();
try {
for (int i = 0; i < targetLength; i++) {
String tem = target.substring(i, i + 1);
int l=(tem.getBytes("utf-8")).length;
if(l==1){
childLength ++;
}else if(l>1){
childLength += 2;
}
if (childLength <= num) {
sb.append(tem);
Log.e("string", "tem is " + tem + "\tlength is " + childLength + "\tsb is " + sb.toString());
} else {
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sb.toString();
}
/**或取字符数 中英混排,甚至emoji混排的 字符串的字符数
* 现在又要把emoji的情况考虑进去,所有用utf-8(可变长度编码集:英文是1个字符;汉子大约是3个,复杂的是4个字符;emoji是4个字符)
* 但是不知道编码的程序设计师们只会认为 英文数字是1个字符,汉字、emoji什么的zh占2个字符
* 所以,用utf-8编码,大于1,也就是非英文数字,即算作2个字符。遂符合设计之意
*/
public static int stringLength(String target) {
int childLength = 0;
int targetLength = target.length();
try {
for (int i = 0; i < targetLength; i++) {
String tem = target.substring(i, i + 1);
int l=(tem.getBytes("utf-8")).length;
if(l==1){
childLength ++;
}else if(l>1){
childLength += 2;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return childLength;
}