26

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

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

我不是在寻找诸如“如果你好什么都不做”之类的解决方法......

4

6 回答 6

27

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

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

这是实现您想要做的任何事情的好方法。TextWatcher然后检查setText是否通过完成来完成并从方法中返回

 void doBeforeTextChanged() {
     if (mBlockCompletion) return;

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

于 2012-10-17T13:38:30.233 回答
15

您可以检查当前哪个 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(myEditText.hasFocus()) {
            // is only executed if the EditText was directly changed by the user
        }
    }

    //...
});

在此处查看该答案的更详细版本。

于 2015-10-12T20:49:30.313 回答
5

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

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

希望这可以帮助!

于 2016-10-26T07:21:00.193 回答
3

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

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

于 2012-10-16T04:26:45.157 回答
3

实现此目的的另一种方法是使用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;
    }
});
于 2014-06-03T15:04:42.433 回答
0

我只能看到两种方式

  • 你在监听器中检查
  • 您根据某些条件添加/删除侦听器

由于第一种方法对您来说是一种不需要的解决方法,我担心您已经使用第二种方法解决了。

于 2012-10-16T04:40:40.243 回答