一个edit text 实现

场景:需要动态生成用于单词填写的一系列edittext,要求是一空填一个字母。Edittext不能点选,填完一个词就进入下一个空格,点击软键盘的删除按钮,就把当前格的字母删除并进入上一个空格。

要点1:动态生成edittext,具体来说就是,每给定一个单词,要根据单词的长度来生成相应数量的edittext,每一个控件能且仅能填写一个字母。

思路①:使用addview的方法,动态地在运行中知道需要的数量之后向布局中添加控件,但是由于不熟悉这个方法,所以没有用;

思路②:比较偷懒的方法,就是直接在布局中预先添加了数十个edittext,然后将所有控件设置为INVISIBLE,在运行过程中直接根据需要,把相应数量的控件设为可见即可。

要点2:填完一个空格之后,需要自动让下一个控件获取焦点。点击软键盘的删除按键之后,要将焦点回退。

思路:为每一个edittext控件设置textwatcher,并设置一个全局计数器,记住当前的edittext下标,例如叫做currentPosition。在aftertextchanged方法里面,如果检测到当前的edittext中获取到的文本已经>=1(实际上每个edittext的最大容纳字符为2,因为删除操作之后,又进行输入操作时的需要),就让下一个控件获取焦点,此外对第一个控件和最后一个控件做一点特殊情况的处理。

至于软键盘的删除键,则可以为每一个edittext设置一个onkeydown监听,可以监听到按下del键的操作。然后使用handler让主线程更新ui。具体更新过程是,把当前要删除的edittext置为空,然后让currentPosition减一,并让上一个edittext控件获取焦点(这里要注意的是,ui上将当前edittext置为空,和手动输入一样,也会触发textwatcher的事件)。同时,因为上一个控件已经输入了字符,此时可以用setselection方法让光标出于最右边,方便接下来的输入。

在删除操作之后的输入,是输入在已经有一个字符的edittext中的,所以这里进行一个小小的操作,在textwatcher里检测到edittext中有两个字符时,就马上将该edittext中的第二个字符截取,并放入下一个edittext中,同时将让下一个edittext获取焦点。这一个特性用split方法即可实现。

要点3:edittext不能点选获取焦点,但能输入。

思路:对每一个edittext重写ontouch方法,其中的操作不重要,但最后返回true值,就可以把点击事件consume掉,以至于edittext无法通过手动点选的方式获取焦点。

此外走过的弯路包括,在布局中调整clickable, enable, 在父控件中加入focusable=true;focusableInTouchMode=true;希望父控件能将点击事件事先consume掉,但是都不能达到效果。

但是这一方法的弊端就是,让edittext完全不可响应,只能根据预先安排好的顺序进行输入。在手动收起软键盘之后不能通过在ontouch方法中调用弹出软件盘的方法。

原文地址:https://www.cnblogs.com/jason31/p/9470811.html