在安卓中我们会经常使用EditText,这个控件允许我们输入字符并获取字符.有时我们需要对输入的字符内容进行过滤,通常情况下是自定义正则表达式,这样定制性更高.但是本节将要讲的是哈斯用InputFilter来过滤输入的文本,同样可以达到正则表达式的部分功能.
InputFilter有两个直接子类,AllCaps和LengthFilter.
InputFilter.AllCaps
这个过滤器将会将输入的所有的英文小写字母变为大写字母.
InputFilter.LengthFilter
这个过滤器会设置一个输入的最大长度,当输入的长度超过设置的最大值时,只显示前边的字符.
该过滤器的作用相当于XML布局文件的maxLength属性.
当你需要在java代码中使用固定长度的方法时你会发现没有setMaxLength方法,我们需要定义一个过滤器数组,然后添加LengthFilter到数组,并赋给给EditText才会产生一个拥有固定长度的EditText.1
2private InputFilter[] filters={new InputFilter.LengthFilter(5)};
editText.setFilters(filters);
这两个类都非常简单,它们主要是利用了InputFilter接口的中的filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
方法来实现对字符的操作.
那么我们可以通过模拟上边两个类来实现我们自己的过滤器,例如:
- 将所有的大写字母转换为小写字母
首先看一下接口文档的方法说明:1
2
3
4
5
6CharSequence filter (CharSequence source,
int start,
int end,
Spanned dest,
int dstart,
int dend)
当缓冲区的字符要使用从source字符串的start到end位置的字符替换dest的字符串的从dstart到dend的字符时会调用这个方法,其实就是输入或者删除字符串的时候.返回的是你替换好的字符串,包括空字符串(如果对此适用),或者null来接受替换操作.注意,当删除字符串时不要忽略对0长度的字符串的替换.同样需要注意的是不要试图更改dest的内容,你只能在上下文中检查dest.如果soruce是Spanned或者Spannable的实例,source应该被复制到过滤后的结果中,使用copySpansFrom(Spanned, int, int, Class, Spannable, int)
方法会更简单.
画一个简单的模型:
我们数据流从键盘接收,然后经过一个缓冲区,最后由缓冲区进入EditText显示.
加上filter以后相当于加上了一个拦截器,此时模型变为:
输入的字符要经过filter转换以后才显示到EditText上.
source相当于缓冲区给filter的字符,dest相当于未更改前的EditText上显示的字符串,当经过我们的filter后会立即转变为输入后filter转换的字符串.
理解了这个原理后我们就可以定义自己的过滤器了.
实现大写转小写的过滤器
1 | ublic class Alllower implements InputFilter { |
此时我们可以测试一下这个过滤器是否有用:1
private InputFilter[] filters={new Alllower(),new InputFilter.LengthFilter(5)};editText.setFilters(filters);
看一下结果:
可以看到只是将大写字母转换为了小写字母,并没有影响其他.
其他实现接口的类
DateKeyListener,DateTimeKeyListener,DialerKeyListener, DigitsKeyListener,TimeKeyListener均继承自NumberKeyListener,而NumberKeyListener实现了InputFilter接口.但是这些都是用来监听硬件输入设备的,暂不研究.
LoginFilter, LoginFilter.PasswordFilterGMail, LoginFilter.UsernameFilterGMail, LoginFilter.UsernameFilterGeneric是实现的一个专门为Gmail登录的过滤器.