如何避免在Android的EditText中执行onTextChanged

jaxagkaj  于 2023-02-02  发布在  Android
关注(0)|答案(6)|浏览(241)

我怎样才能避免这样的代码行:

((EditText) findViewById(R.id.MyEditText)).setText("Hello");

将在此处引发事件:

((EditText) findViewById(R.id.MyEditText)).addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start,
    int before, int count) {
// HERE
}

@Override
public void beforeTextChanged(CharSequence s, int start,
    int count, int after) {
}

@Override
public void afterTextChanged(Editable s) {
}
});

我想知道是否有任何方法可以禁止执行onTextChanged,正如我在选择AutoCompleteTextView的下拉结果时所注意到的那样(没有执行onTextChanged!)。
我不是在寻求“如果你什么都不做”之类的解决办法...

pw136qt2

pw136qt21#

AutoCompleteTextView的源代码显示,他们设置了一个布尔值,表示文本将被块完成替换

mBlockCompletion = true;
         replaceText(convertSelectionToString(selectedItem));
         mBlockCompletion = false;

这是实现您想要的操作的最好方法。然后TextWatcher检查setText是否通过完成操作到达并从方法中返回

void doBeforeTextChanged() {
     if (mBlockCompletion) return;

添加和移除TextWatcher将耗费应用程序更多的时间

qij5mzcb

qij5mzcb2#

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

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
        }
    }

    //...
});

请看here,以获得更详细的答案。

qvsjd97n

qvsjd97n3#

或者,您可以简单地使用mEditText.hasFocus()来区分文本是人为更改的还是程序更改的,这对我来说很好:

@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
    if (mEditText.hasFocus()) {
        // Do whatever
    }
}

希望这有帮助!

xriantvc

xriantvc4#

另一种实现方法是使用setOnKeyListener
这将仅在用户按下某个键时触发,而不是在用户或以编程方式更改EditText时触发。

myEditText.setOnKeyListener(new EditText.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        switch(event.getAction()) {
            case KeyEvent.ACTION_DOWN:
                // beforeTextChanged
                break;      
            case KeyEvent.ACTION_UP:
                // afterTextChanged
                break;
        }
        return false;
    }
});
3bygqnnd

3bygqnnd5#

我不认为有一个简单的方法来禁用侦听器,但您可以通过以下任一方法来绕过它:

  • 在设置文本之前删除TextWatcher,然后将其添加回去。
  • 或者在设置文本之前设置一个boolean标志,它告诉TextWatcher忽略它。

例如

boolean ignoreNextTextChange = true;
((EditText) findViewById(R.id.MyEditText)).setText("Hello");

在您的TextWatcher中:

new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        /*
        If the flag is set to ignore the next text change,
        reset the flag, and return without doing anything.
        */
        if (ignoreNextTextChange) {
            ignoreNextTextChange = false;
            return;
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

这是一个有点hacky,但它应该工作:)

llycmphe

llycmphe6#

我只能从两个方面看

  • 在监听器中检查
  • 根据特定条件添加/删除侦听器

由于第一种方法对您来说是一种不需要的变通方法,恐怕您必须使用第二种方法。

相关问题