先上效果图吧,这个相对来说比较简单,但是真正实现的时候,之前实习的时候做过一个简陋的,有很多很多的瑕疵,现在得空了就把这个功能简单的逻辑理清一下,顺便巩固一下对EditText的使用(需要现在很多App中的输入框很少),先上一下效果图:

lgr6ablhzm7HjhiK.png

布局如图所示

在实现具体功能之前,先来讲讲TextWatcher的三个函数,已经了解的可以略过。

1、**beforeTextChanged(CharSequence s, int start, int count, int after)**

在这方法内不能够对EditText进行修改操作,否则会报错。

第一个参数s是对EditText进行**增删改**变化之前的字符序列,需要考虑到EditText的选定文本状态,因为我们可以对文本进行多个字符的操作。

第二个参数start是发生变化的起始点,关于起始点其实还不是很好理解,当我们删掉C的时候,这时start为**2**,注意了,此时光标应该在B后面,这个时候我们再输入一个C,会发现此时的光标也是2,这是因为当我们进行删除的时候,从2位置开始进行删除,而添加的时候是从2位置开始进行添加。所以虽然光标在3,但是实际start的位置为2.**这个开始位置并不能理解为光标的位置**。

fVJ1zdi7jgkyCeHZ.png

,第三个参数count和第四个参数after指的是,用after个字符替换掉count个字符。如果在图中C后面输入一个字符,count就是0,after就是1,如果删除C,那么count就是1,after就是0,对于多字符的操作也是同理。

2、**onTextChanged(CharSequence s, int start, int before, int count)**

对于这个函数,其实很多都是相似的,不一样的地方是:

第一个参数s代表的是,变化后的结果,就是说在上图C后面输入D,那么这个s的值就是ABCD。

第二个参数是开始位置,和**beforeTextChanged中**的start含义一样**。**

第三个参数是before,待替换字符的个数。

第四个参数是count,替换字符的个数。

3、**afterTextChanged(Editable s)**

这个函数只有在文本不再发生变化后才会调用,试想如果你在onTextChanged函数里进行了setText,那么afterTextChanged不会被调用,而是再次调用beforeTextChanged,当文本停止变化,就会有一系列的afterTextChanged调用(所以小心在afterTextChanged中的操作,因为一次的setText就会触发一次的afterTextChanged!!!)

参数里面的s就是文本发生改变后的结果值。

最后,记住,**当我们调用setText的时候,就会马上调用这几个回调函数!**

介绍完EditText中的三个重要的文本监听的回调函数后,就进入正文部分了。

先来分析一下实现手机格式化的需求

1、首先是输入框的输入过滤,天知道用户会输入什么东西进来,所以我觉得输入框的过滤是必不可少的,因为搞不好可能就会出现各种各样的bug。在这里我们只允许用户输入**阿拉伯数字**。方法有很多种,这里用最简单的方式设置InputType即可

dIXV8InrKS2flQkg.png

输入类型为数字

2、对于限制数字输入,其实还可以自定义InputFilter来实现的,这里使用InputFilter来限制输入的字数限制。

pZ6Yzdr9DghSuEpq.png

输入字数限制为13个

3、设置完只能够输入数字后,那么工作量就少了许多许多了,接下来就是如何让输入的数字变成344的组合,注意,设置输入类型并不能够影响setText,如果在setText里面设置字母,那么还是会显示字母的。

第一步,设置边界

PNNRALfObCkl6Kg4.png

第二步,接下来就是关键部分了,可能实现这个功能有很多种方法,但是在我实现这个功能的时候,如果不注意的话,可能就会跟网上的其他demo一样,当用户进行删除的时候就会出bug。

先说上一部分,就是当**isUserInput**为true,用户正常输入的时候,这一部分其实很简单,只要关注输入内容的长度,因为当**isUserInput**为true的时候,用户只可能输入了一个数字,取得所有的数字,直接按情况添加空格即可(要换成-号或者分成355的格式也是同理),记得在最后面去修改状态,不然就会死循环。

qVD0LwfSTW1pVfoZ.png

下一部分就是我认为是难点之一,我说之一,是因为下面还有一个难点。当用户在任意位置删除一个或多个数字的时候,如何确保删除后的格式是正确的,关于这一部分,我想了很多种方式,但是依然没想到一种快捷的方式来实现,最后就只能使用最笨的枚举法了。

gkN8cOr6VaL5wffm.png

当删除后的手机格式不正确,那么按照上面的方法遍历即可,当用户顺序删除的时候,还要考虑到最后文本的最后一个是空格,那么就直接把空格去掉,这也只是为了让程序少一点循环而已...上图的数字应该还是很好理解的,要是不理解的话,直接画一下图就可以了。

如何判断当前是否为合法的手机号格式

直接上代码就好了,这部分直接枚举所有合法的情况,因为合法的情况下,第四个位置和第九个位置应该是空格,这就是手机格式化的本质。一开始我也是绕了很多的弯路啊。

gpURSnhG8apyTolW.png

3种合法情况

而最后一个难点,我还没有十分完美地解决,就是关于输入框内的Selection,因为我们不能无脑地把selection设置在文本的末尾,因为不能够用户在中间修改一个符号,就把光标设走啊,但是单纯用start这个发生变化的位置也不能够解决,因为如果添加了空格,就需要把空格也考虑进去,要真正实现光标的移动也是可以的,但是我认为这样的话,需要设成员变量来记录光标,不是很喜欢这种方法。关于手机格式化的EditText就到这里了,关键部分还是**TextWatcher**的逻辑,把这个TextWatcher封装到一个EditText里即可直接使用。

接下来是实现一个自动补全邮箱域名的EditText,这个的话,我觉得稍微复杂一点点,但是要是有这个,对于使用邮箱作为登录账号的app,体验是蹭蹭蹭的上升啊。

你可能感兴趣的内容
0条评论
MI

mikemaccana

这家伙太懒了,什么都没留下
Owner