如何在不触发文本观察程序的情况下更改编辑文本文本?

我有一个带有客户文本观察程序的字段。在一段代码中,我需要更改编辑文本中的值,我使用.EditText.setText("whatever")

问题是,一旦我进行更改,方法就会被调用,从而创建一个无限循环。如何在文本更改后不触发文本的情况下更改文本?afterTextChanged

我需要 afterTextChanged 方法中的文本,因此不建议删除 .TextWatcher


答案 1

简短的回答

您可以检查哪个视图当前具有焦点,以区分用户和程序触发的事件。

EditText myEditText = (EditText) findViewById(R.id.myEditText);

myEditText.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (myEditText.hasFocus()) {
            // is only executed if the EditText was directly changed by the user
        }
    }

    //...
});

长答案

作为简短答案的补充:如果您以编程方式更改应调用的文本时已经具有焦点,那么您可以呼叫并在重新请求焦点之后。最好将其放在实用程序函数中:myEditTextclearFocus()setText(...)

void updateText(EditText editText, String text) {
    boolean focussed = editText.hasFocus();
    if (focussed) {
        editText.clearFocus();
    }
    editText.setText(text);
    if (focussed) {
        editText.requestFocus();
    }
}

对于 Kotlin:

由于 Kotlin 支持扩展函数,因此您的实用程序函数可能如下所示:

fun EditText.updateText(text: String) {
    val focussed = hasFocus()
    if (focussed) {
        clearFocus()
    }
    setText(text)
    if (focussed) {
        requestFocus()
    }
}

答案 2

您可以注销观察程序,然后重新注册它。

或者,您可以设置一个标志,以便您的观察者知道您何时刚刚自己更改了文本(因此应忽略它)。


推荐