TextWatcher事件被多次触发

我有一个恼人的TextWatcher问题。 我一直在网上search,但没有find任何东西。 感谢有人能帮助我。

出于某种原因, 在一次文本更改时对TextWatcher事件的调用是不稳定的。 有时他们被触发一次(像他们应该),有时两次,有时是三次。 不知道为什么,整个事情非常直截了当。 有时候,afterTextChanged()的Editable参数会返回toString()和length()中的空值。

代码如下:

private TextWatcher mSearchAddressTextChangeListener = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable searchedAddress) { System.out.println("called multiple times."); } }; 

里面afterTextChanged() (和AsyncTask )我不做任何改变的文字或EditText视图。

我看到在TextWatcher事件中提出的问题被称为两次 ,但即时通讯事件触发更多(或less于)两次。

无论如何,感谢任何帮助。

编辑:我删除了afterTextChanged()的内容,导致即使没有我的代码发生这个问题。 是什么让我相信这是一个错误。 当一个普通的char(事件处理程序被触发两次)或者一个普通的char被移除(退格事件处理程序被触发三次)之后的一个“空格”字符之后立即input“空格”字符时,就会发生这个错误。 帮助仍然将不胜感激。

我有同样的问题,当我用连续的文本结尾处的光标退格键时,afterTextChange被调用了3次: – 第一次使用正确的s值 – 第二次使用明确的值 – 第三次与再次正确的价值

在网上search了很多之后,我试着改变我的EditText inputType

 android:inputType="textNoSuggestions" 

不要问我为什么,但它的工作,afterTextChanged现在只调用一次。

根据TextWatcher的开发者页面,如果对TextWatcher中的Editable进行了TextWatcher ,它将触发对所有链接到该EditableTextWatchers进一步调用。 现在,显然你的代码不会触发这种行为。

但是,如果出于某种原因,系统在“ Editable上具有TextWatcher ,则很有可能出现您描述的情况。 “为什么”,我听到你哭,“这是否应该发生?

首先,经典的防御:没有理由不发生,严格地说,应该编写应用程序代码来对其进行修复。

其次,我无法certificate这一点,但我可以想象,处理EditText显示文本的布局的代码使用TextWatcher来处理更新屏幕上文本的显示。 此代码可能会将控制代码(您未显示)插入到Editable以确保良好的换行符等等。 它甚至可能会循环几次才能得到正确的结果,并且在完成所有操作之后,您可能只会收到您的第一个电话。

编辑

根据@Learn OpenGL ES的评论,TextWatcher的调用对于像autocorrect这样的东西来说是正常的。

 boolean isOnTextChanged = false; @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { isOnTextChanged = true; } @Override public void afterTextChanged(Editable quantity) { if (isOnTextChanged) { isOnTextChanged = false; //dosomething } 

你可以使用布尔检查,如:

  inputBoxNumberEt.addTextChangedListener(new TextWatcher() { boolean ignoreChange = false; @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (!ignoreChange) { ///Do your checks ignoreChange = true; inputBoxNumberEt.setText(string); inputBoxNumberEt.setSelection(inputBoxNumberEt.getText().length()); ignoreChange = false; } } });