前言
在實際的開發當中,如果有一個需求是:
- 輸入框中只能輸入中文或者是英文亦或者是中英混合
- 如果是純英文,長度限制是12,其他情況限制為6。
分析
當你看完上面的需求時,是不是有種想法想提刀斬需求方? WTF !
大胸弟,莫雞凍。
我們先想想,有神碼方法是可以限制輸入框上輸入的呢?哎,好像有個叫inputType的屬性哦。。。可是翻遍了所有的屬性,都沒有我們所需要的啊 !
android:inputType="text|textCapWords|number|textPassword|..."
好吧,既然沒有,在看看有沒有其他的屬性咯.
android:digits="0123456789"
這個屬性,好像是可以的 ? 但是這個屬性是只允許輸入的是digits里面所定義的所有規則 , 如果我要輸入的是中英文 , 要怎樣去寫里面的規則呢 ? 很明顯這個屬性里面的值是不支持正則表達式的,所有無法完成。
有人會說 , 不能在用戶輸入內容后再在處理時判斷嗎 ? Are you kidding me ? 你做不好事情 , 到時候可能就是需求方找你麻煩了.不過又給了你一個接觸他kan他的機會了, 珍重 !
做法
有的人說 , 用TextWatcher來監聽輸入 , 然后判斷是否是需要的 , 不需要的就用空的字符串替換掉 , 然后把光標移動到相應的位置 , 這種方式有興趣的朋友可以試試 .
下面我說說我的做法 :
其實google大佬是很聰明的啦 , 神碼都為我們想好了 , EditText 中有個方式是
setFilters(InputFilter[] InputFilter)
我們可以用這個方法做很多事情的 , 比如上面所說的限制只能輸入中英文 .
首先定義一個InputFilter
InputFilter typeFilter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
Pattern p = Pattern.compile("[a-zA-Z|\u4e00-\u9fa5]+");
Matcher m = p.matcher(source.toString());
if (!m.matches()) return "";
return null;
}
};
里面的內容也是一看就能明白的 , 其中如果需要輸入該字符串的話就返回null , 如果要過濾掉(不要)的話就返回空字符串 .
然后再設置 :
editText.setFilters(new InputFilter[]{typeFilter});
注意
這里有個注意的地方是 , 如果設置了inputFilter , 那么在布局中設置的maxLength屬性就會失效 , 那么怎樣去限制它的長度呢 ?
如果是統一的長度的話 , 直接設置即可 .
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(length)});
如果想需求中的根據每種情況設置不同的長度限制怎么辦 ? 那就自己寫唄 .
private static class SizeFilterWithTextAndLetter implements InputFilter {
private int mMaxLength;
private int onlyLetterLength;
private int normalLength;
private boolean hasChinese;
Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
Matcher m;
private SizeFilterWithTextAndLetter(int onlyLetterLength,int normalLength) {
this.normalLength = normalLength;
this.onlyLetterLength = onlyLetterLength;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (!hasChinese && dest.length() <= normalLength) {
if (dest.length() >= normalLength) {
m = p.matcher(dest.toString());
} else {
String tmp = source.toString() + dest.toString();
if (tmp.length() >= normalLength) {
tmp = tmp.substring(0,normalLength);
}
m = p.matcher(tmp);
}
hasChinese = m.find();
mMaxLength = hasChinese ? normalLength : onlyLetterLength;
}
if (mMaxLength == onlyLetterLength) {
m = p.matcher(source);
if (m.find()) return "";
}
int keep = mMaxLength - (dest.length() - (dend - dstart));
if (keep <= 0) {
return "";
} else if (keep >= end - start) {
return null;
} else {
keep += start;
if (Character.isHighSurrogate(source.charAt(keep - 1))) {
--keep;
if (keep == start) {
return "";
}
}
return source.subSequence(start, keep);
}
}
}
然后
editText.setFilters(new InputFilter[]{new SizeFilterWithTextAndLetter(12,6)});
大功告成 !!!
附上demo地址吧 , 需要的就看看咯 .