本文只是记录一些零碎的东西
要求输入框最多输入6个中文,12个英文
主要是监听输入框变化
如何使用
EditText.addTextChangedListener(new SketchTextWatcher(mTitleContent));
InputFilter[] filters = {new SketchLengthFilter()};
EditText.setFilters(filters);
自己处理的两个类:
private static class SketchTextWatcher implements TextWatcher {
private int editStart;
private int editEnd;
private int maxLen = 12; // 6 个汉字 12 个英文字符 (表情 2 个字符)
private EditText editText;
public SketchTextWatcher(EditText e) {
editText = e;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
D.i("slack", "afterTextChanged..." + s);
editStart = editText.getSelectionStart();
editEnd = editText.getSelectionEnd();
// 先去掉监听器,否则会出现栈溢出
editText.removeTextChangedListener(this);
if (!TextUtils.isEmpty(s.toString())) {
while (calculateLength(s.toString()) > maxLen) {
s.delete(--editStart, editEnd--);
D.i("slack", "editStart = " + editStart + " editEnd = " + editEnd + " s = " + s);
}
}
editText.setText(s);
editText.setSelection(editStart);
// 恢复监听器
editText.addTextChangedListener(this);
}
/**
* 英文一个字符 中文两个字符
*/
private int calculateLength(String string) {
char[] ch = string.toCharArray();
int varlength = 0;
for (char c : ch) {
// changed by zyf 0825 , bug 6918,加入中文标点范围 , TODO 标点范围有待具体化
if ((c >= 0x2E80 && c <= 0xFE4F) || (c >= 0xA13F && c <= 0xAA40) || c >= 0x80) { // 中文字符范围0x4e00 0x9fbb
// if (c >= 0x4E00 && c <= 0x9FBB) { // 中文字符范围 0x4E00-0x9FA5 + 0x9FA6-0x9FBB
varlength = varlength + 2;
} else {
varlength++;
}
}
D.i("slack", "length : " + varlength + " l: " + string.length());
return varlength;
}
}
/**
* 纯英文 纯中文 可以实现 from : http://justwyy.iteye.com/blog/1543419
* 中英混输入 :
* 中文 占 2 位
* 英文 占 1 位
* 思路:计算 已有文字的长度,计算新增文字的长度,长度没有到达限制时,拼接
* 小米 输入时,没有边输入边写入EditText的手机有问题,比如小米
* 华为这种输入一个字符就写入的,没有问题
*/
private static class SketchLengthFilter implements InputFilter {
private final int LENGTH_ENGLISH;
SketchLengthFilter() {
this(12);
}
SketchLengthFilter(int english) {
LENGTH_ENGLISH = english;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
int keep = LENGTH_ENGLISH - (calculateLength(dest.toString()) - (dend - dstart));
end = calculateLength(source.toString());
D.i("slack", "source("+start+","+end+")="+source+",dest("+dstart+","+dend+")="+dest + " keep:" + keep);
CharSequence result = "";
if(keep >= 0) {
if (keep >= end - start) {
result = null; // keep original
} else {
result = subSequence(source.toString(), start, start + keep);
}
}
D.i("slack","result : " + (result == null ? "null": result) + ".");
return result;
}
private CharSequence subSequence(@NonNull String source,int start,int length){
int size = calculateLength(source);
if(size < length){
return source;
}
char[] chars = source.toCharArray();
if(chars.length < length){
return source;
}
char[] result = new char[length - start];
System.arraycopy(chars, start , result, 0, length);
return new String(result);
}
private int calculateLength(String string){
int length = 0;
char[] chars = string.toCharArray();
for (char c : chars) {
if (isChinese(c)) {
length += 2;
} else {
length++;
}
}
return length;
}
private boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
}
}