Как я могу избежать выполнения onTextChanged в EditText Android

Как я могу избежать такой строки кода, как:

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

Я не ищу обходные пути, как «если привет ничего не делает» …

Solutions Collecting From Web of "Как я могу избежать выполнения onTextChanged в EditText Android"

Источник для AutoCompleteTextView показывает, что они устанавливают логическое значение, чтобы сказать, что текст заменяется завершением блока

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

Это так же хорошо, как любой, чтобы достичь того, что вы хотите сделать. Затем TextWatcher проверяет, пришел ли setText через завершение и возвращается из метода

  void doBeforeTextChanged() { if (mBlockCompletion) return; 

Добавление и удаление TextWatcher потребует больше времени для приложения

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

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

Альтернативным способом достижения этого было бы использовать 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; } }); 

Я не думаю, что есть простой способ отключить слушателя, но вы можете обойти его:

  • Удаление 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) { } }); 

Это немного взломанный, но он должен работать 🙂

Только два пути, которые я могу видеть

  • Вы проверяете внутри слушателя
  • Вы добавляете / удаляете слушателя в соответствии с определенными условиями

Поскольку первым способом является нежелательное обходное решение для вас, я боюсь, что вы работаете со вторым способом.

В качестве альтернативы вы можете просто использовать mEditText.hasFocus() чтобы различать текст, измененный человеком или измененный программой, это отлично работает для меня:

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

Надеюсь это поможет!