EditText inTextInputLayout 仅针对第一个字母调用 onTextChanged 两次

EditText inTextInputLayout calls onTextChanged twice for first letter only

我正在开发一个开源文本屏蔽器。您可以点击here查看源代码。

我的问题是,当我用 TextInputLayout 包裹我的自定义编辑文本时,onTextChanged 仅针对第一个字母被触发两次。然后它按预期工作。

这个“两次调用”打破了我的逻辑。你们知道可能是什么问题吗?由于它正被其他开发人员使用,我不想用 hacky 解决方案修复它。我需要找出问题所在。

我在删除文本观察器后手动设置文本,然后我再次添加文本观察器。

这是我的主要逻辑;

此方法仅被调用一次;

   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
    }

我的 class 像 TextInputEditText 一样扩展了 AppCompatEditText。

如果您从 onCreate() 或 init() 调用 addTextChangedListener() 将调用移至 onResume() 或稍后调用的任何其他函数,否则 onTextChanged() 会在恢复之前触发