当有一系列包含 1 个符号(通常的 pin 码)的字段时,我也遇到了这种情况。
我的解决方案基于@jmeinke 的回答。
创建一个包含多个 EditTexts 和 android:maxLength="2" 的布局(我们将在其中输入一个符号并跳转到另一个 EditText。奇怪,但在某些手机上,即使 maxLength=1 也可以使用下面的代码) .
class YourTextWatcher(
private val prevEdit: EditText?,
private val currEdit: EditText,
private val nextEdit: EditText?,
private val method: () -> Unit
) : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (s.isNullOrEmpty()) {
prevEdit?.requestFocus()
} else {
if (s.length > 1) {
if (currEdit.selectionEnd > 1) {
// If stand on second position of EditText and enter new symbol,
// will move to next EditText copying second symbol.
val secondSymbol = s.substring(1, 2)
nextEdit?.setText(secondSymbol)
}
// Remove second symbol.
s.delete(1, s.length)
}
nextEdit?.requestFocus()
nextEdit?.setSelection(nextEdit.length(), nextEdit.length())
method()
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
然后对所有EditTexts 执行以下操作:
currEdit.addTextChangedListener(
YourTextWatcher(prevEdit, currEdit, nextEdit) { yourMethodToValidateText() })
而不是 prevEdit、currEdit、nextEdit 设置您的EditText 控件。例如,对于第一个:
edit1.addTextChangedListener(
YourTextWatcher(null, edit1, edit2) { yourMethodToValidateText() })
yourMethodToValidateText() 是一种检查输入符号的方法。例如,您可以检查是否所有EditTexts 都已填满。
当您尝试在空的EditText 中按 BackSpace 时,此解决方案存在错误。什么都没有发生,你不会去以前的EditText。您可以在 View.OnKeyListener 中捕获 BackSpace,但它可以与 TextWatcher 相交。另外,我在将文本复制并粘贴到 EditText 时没有检查情况,忘记检查在 EditText 中选择文本并按 Delete 时会发生什么。