项目的需求中,又一个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);来开启软键盘。