EditText文本输入框,非常常见的一个控件。在使用时常常会限制用户输入的长度,一般来说直接在xml里面设置android:maxlength即可。但有时候有些场景,比如输入名称,可以输入中文和字母,但是中文算两个字符长度,这时设置maxlength可能就不太符合我们的需求了。为了让用户输入足够的字符后不允许输入,就需要使用TextWatcher来对输入进行控制。具体代码如下
/**
* 限定输入名称长度(中文算两个长)
*/
public class NameWatcher implements TextWatcher {
private int maxLength = 10;
private EditText mEditText;
public NameWatcher(EditText editText, int maxLength) {
this.mEditText = editText;
this.maxLength = maxLength;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/**
* @param s editText设置的值
* @param start 光标从哪里开始输入
* @param before
* @param count 此次输入的字符长度
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int totalLength = getWordCount(s.toString());
if (totalLength > maxLength) {
//当前输入的字符
CharSequence input = s.subSequence(start, start + count);
int inputLength = getWordCount(input.toString());
//有效字符
String valid = getLimitString(input, maxLength - (totalLength - inputLength));
if (start + count == s.length()) {
//在最末尾添加的字符
mEditText.setText(String.valueOf(s.subSequence(0, start) + valid));
mEditText.setSelection(mEditText.getText().length());
} else {
//在中间添加的
mEditText.setText(String.valueOf(s.subSequence(0, start)
+ valid
+ String.valueOf(s.subSequence(start + count, s.length()))));
mEditText.setSelection(start + valid.length());
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
/**
* 获取字符串长度
* 由于Java是基于Unicode编码的,因此,一个汉字的长度为1,而不是2。
* 要以字节单位获得字符串的长度。
* 例如,“123abc长城”按字节长度计算是10,而按Unicode计算长度是8。为了获得10,
* 需要从头扫描根据字符的Ascii来获得具体的长度。如果是标准的字符,Ascii的范围是0至255
* ,如果是汉字或其他全角字符,Ascii会大于255。
*
* @param s
* @return
*/
public int getWordCount(String s) {
int length = 0;
for (int i = 0; i < s.length(); i++) {
int ascii = Character.codePointAt(s, i);
if (ascii >= 0 && ascii <= 255)
length++;
else
length += 2;
}
return length;
}
/**
* 限制长度的字符
*
* @param str
* @param maxLength
* @return
*/
private String getLimitString(CharSequence str, int maxLength) {
int length = 0;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
int ascii = Character.codePointAt(str, i);
if (ascii >= 0 && ascii <= 255) {
if (length < maxLength) {
length++;
stringBuilder.append(str.charAt(i));
} else {
return stringBuilder.toString();
}
} else {
if (length + 2 <= maxLength) {
length += 2;
stringBuilder.append(str.charAt(i));
} else {
return stringBuilder.toString();
}
}
}
return stringBuilder.toString();
}
}
使用:
mEtName.addTextChangedListener(new NameWatcher(mEtName, 20));
顺带记录一下,inputType设置为“number”的话是不允许输入空格的,而设置为“phone”则可以输入空格。