项目的需求中,又一个4位数的验证码界面,小弟才疏学浅,只想到了用线性布局里面放四个EditText。
需求需要输入内容后,自动跳到下一个位置聚焦,删除指定位置后,自动跳到上一个位置聚焦,由于聚焦/非聚焦UI展示得都不同,所以每个editText都会频繁的设置焦点变化。
之前因为是调用的系统键盘,所以,editText和键盘绑定后处理起来非常方便,但是,我们需要自定义一个展示在UI上的数字键盘,于是就有些bug。
bug不难,但是有点杂乱,下面是我的一点解决办法,总结一下,以后也记得更清楚!
1、首先是实现输入内容后,自动跳到下一个位置聚焦:
实现方式:TextWatcher监听内容输入后,设置此位置失去焦点,下个位置获取焦点(由此控制UI变化)
var textWatcher: TextWatcher = object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable) { if (!s.toString().isEmpty() && currentPosition < editTextList.size() - 1) { editTextList.get(currentPosition).setFocusable(false) //下个位置自动聚焦 currentPosition++ editTextList.get(currentPosition).setFocusable(true) editTextList.get(currentPosition).setFocusableInTouchMode(true) editTextList.get(currentPosition).requestFocus() editTextList.get(currentPosition).findFocus() } } }
tips:之前我只调用了requestFocus(),但是有概率会失败,因为我会在操作的过程中调用setFocusable(false),所以,稳妥的办法就是:
editTextList.get(currentPosition).setFocusable(true);//设置输入框可聚焦 editTextList.get(currentPosition).setFocusableInTouchMode(true);//设置触摸聚焦 editTextList.get(currentPosition).requestFocus();//请求聚焦 editTextList.get(currentPosition).findFocus();//获取焦点
2.删除内容后,设置为失去焦点,跳到有内容的位置,得到焦点
fun deleteContent() { editTextList.get(currentPosition).setText("") if (currentPosition > 0) { editTextList.get(currentPosition).setFocusable(false) editTextList.get(currentPosition) .setBackground(ContextCompat.getDrawable(context, R.drawable.rgb_282730_r12)) //跳到前一个不为空的EditText for (position in currentPosition downTo 0) { currentPosition = position if (!editTextList.get(position).getText().toString().isEmpty()) { isDelete = true editTextList.get(currentPosition).setBackground( ContextCompat.getDrawable( context, R.drawable.rgb272830_stroke_r12 ) ) editTextList.get(currentPosition).setFocusable(true) editTextList.get(currentPosition).setFocusableInTouchMode(true) editTextList.get(currentPosition).requestFocus() editTextList.get(currentPosition).findFocus() break } } } }
3.这是焦点监听:为editText列表根据isFocused设置背景
var onFocusChangeListener = OnFocusChangeListener { v: View?, hasFocus: Boolean -> for (i in editTextList.indices) { if (editTextList.get(i).isFocused()) { currentPosition = ieditTextList.get(i).setBackground() } else { editTextList.get(i).setBackground() } } }
tips:
1. edittext禁止调出软键盘(之前用editText.setFocusable(false);这方法来实现点击跳转,但是这次需要输入内容,不准跳出键盘,所以用下面这个方法)
editText.setInputType(InputType.TYPE_NULL);来禁止手机软键盘。 (xml中设置inputType为none无效)
2.editText.setInputType(InputType.TYPE_CLASS_TEXT);来开启软键盘。