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

时间:2012-10-09 14:28:21

标签: android android-edittext

如何避免代码行如下:

((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!)。

我不是在寻找像“如果你什么也不做”的解决方法......

6 个答案:

答案 0 :(得分:24)

AutoCompleteTextView的来源显示他们设置了一个布尔值来表示文本正在被块完成替换

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

这是达到你想要做的任何事情的好方法。 TextWatcher然后检查以查看setText是否通过完成并返回方法

 void doBeforeTextChanged() {
     if (mBlockCompletion) return;

添加和删除TextWatcher对于应用程序来说会更耗时

答案 1 :(得分:11)

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

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

myEditText.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        if(getCurrentFocus() == myEditText) {
            // is only executed if the EditText was directly changed by the user
        }
    }

    //...
});

答案 2 :(得分:2)

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

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

E.g。

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,但它应该工作:)

答案 3 :(得分:2)

实现此目的的另一种方法是使用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;
    }
});

答案 4 :(得分:2)

或者你只需​​使用mEditText.hasFocus()来区分人为改变或程序改变的文本,这对我来说很好:

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

希望这有帮助!

答案 5 :(得分:0)

我只能看到两种方式

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

由于第一种方式是针对您的不必要的解决方法,我担心您可以使用第二种方法。