* 描述:監聽輸入框輸入的字符數 * 要注意: * 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;
}
}
});