(转载)/p/690c46d58aeb
前言
在实际的开发当中,如果有一个需求是:
输入框中只能输入中文或者是英文亦或者是中英混合如果是纯英文,长度限制是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() {@Overridepublic CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {Pattern p = pile("[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 = pile("[\u4e00-\u9fa5]+");Matcher m;private SizeFilterWithTextAndLetter(int onlyLetterLength,int normalLength) {this.normalLength = normalLength;this.onlyLetterLength = onlyLetterLength;}@Overridepublic 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地址吧 , 需要的就看看咯 .
作者:非常好听的昵称
链接:/p/690c46d58aeb
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
// -------------------------------------------------
(1)可以使用正则表达式来处理只允许输入汉字和英文;
(2)maxLength失效的问题;
(3)InputFilter.LengthFilter可以限制长度输入;