События TextWatcher запускаются несколько раз

У меня есть раздражающая проблема с TextWatcher. Я искал в Интернете, но ничего не нашел. Если кто-то может мне помочь.

По некоторым причинам вызовы событий TextWatcher при одном изменении текста являются неустойчивыми. Иногда они срабатывают один раз (как и должно быть), иногда два раза, а иногда и 3 раза. Не знаю, почему, все это очень прямолинейно. Также иногда параметр Editable на afterTextChanged () возвращает пустые значения в 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 ) im, не изменяя текст или вид EditText .

Я видел, что вопрос, заданный в Events of TextWatcher, вызывается дважды , но im имеет события, вызванные больше (или меньше), чем два раза.

В любом случае, оцените любую помощь.

EDIT: я удалил содержимое afterTextChanged (), потому что эта проблема происходит даже без моего кода. Что заставляет меня думать, что это ошибка. Ошибка возникает, когда символ «пробел» вводится сразу после регулярного символа (обработчики событий запускаются дважды) или когда символ «пробел» после обычного символа удаляется (backspace. Обработчики событий запускаются 3 раза). Помощь по-прежнему будет оценена.

Solutions Collecting From Web of "События TextWatcher запускаются несколько раз"

У меня была такая же проблема, когда я нажал кнопку backspace с курсором в конце непрерывного текста, после того, как TextChange был вызван 3 раза: – первый раз с правильным значением s – второй раз с четким значением – третий раз с Правильное значение снова

После многого поиска в Интернете я попытался изменить свой входной текст EditText на

 android:inputType="textNoSuggestions" 

Не спрашивайте меня, почему, но это сработало, afterTextChanged теперь вызывается только один раз.

Согласно страницам разработчиков для TextWatcher , если внесение изменений в Editable в TextWatcher , это вызовет дальнейшие вызовы для всех TextWatchers связанных с этим Editable . Теперь, очевидно, ваш код не вызывает такого поведения.

Однако вполне возможно, что если по какой-либо причине система имеет TextWatcher в Editable , ситуация, о которой вы описываете, может произойти. «Почему», я слышу, как ты плачешь, «если это произойдет?»

Во-первых, классическая защита: нет никаких причин, чтобы этого не произошло, и, строго, код приложения должен быть написан, чтобы быть устойчивым к нему.

Во-вторых, я не могу это доказать, но я вполне мог представить, что код, который обрабатывает макет отображаемого текста в EditText использует TextWatcher для обработки обновления текста на экране. Этот код может вставлять управляющие коды (которые вы не показываете) в Editable чтобы обеспечить хорошие разрывы строк и так далее. Он может даже обойти цикл несколько раз, чтобы понять это правильно, и вы можете получить свой первый звонок после того, как он выполнил все его …

РЕДАКТИРОВАТЬ

Согласно комментарию @Learn OpenGL ES, вызов TextWatcher был бы нормальным для таких вещей, как автокоррекция.

 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 } 

U может использовать логическую проверку, например:

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