我正在开发一个开源文本掩码器。您可以单击此处查看源代码。
我的问题是,当我用 TextInputLayout 包装我的自定义编辑文本时,onTextChanged 只针对第一个字母被触发两次。然后它按预期工作。
这个"两次通话"打破了我的逻辑。你们知道可能有什么问题吗?由于它被其他开发人员使用,我不想用黑客解决方案修复它。我需要找出问题所在。
删除文本观察器后,我手动设置了文本,然后再次添加文本观察器。
这是我的主要逻辑;
此方法仅调用一次;
private fun initTextWatcher() {
textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
masker?.onTextChanged(s, start, count, before)
}
}
addTextChangedListener(textWatcher)
}
这就是我手动设置文本的方式;
private fun setEditTextWithoutTriggerListener(newText: String) {
removeTextChangedListener(textWatcher)
onTextChangedListener?.invoke(newText) // This is a custom listener.
setText(newText)
setSelection(text?.length ?: 0) // This puts cursor at the end of the text.
addTextChangedListener(textWatcher)
}
为了像TextInputEditText那样处理提示位置,我只是简单地将其函数复制到我的函数中。
override fun getHint(): CharSequence? {
val layoutHint = getTextInputLayout()?.hint
return layoutHint ?: super.getHint()
}
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
val ic = super.onCreateInputConnection(outAttrs)
if (ic != null && outAttrs.hintText == null) {
outAttrs.hintText = getHintFromLayout()
}
return ic
}
private fun getTextInputLayout(): TextInputLayout? {
var parent = this.parent
while (parent is View) {
if (parent is TextInputLayout) {
return parent
}
parent = parent.getParent()
}
return null
}
private fun getHintFromLayout(): CharSequence? {
val layout = getTextInputLayout()
return layout?.hint
}
我的类像TextInputEditText一样扩展AppCompatEditText。
如果你从onCreate((或init((调用addTextChangedListener((,将调用移动到onResume((或稍后调用的任何其他函数中,否则onTextChanged((在恢复之前触发