Андроид на прослушивателе изменения текста

У меня есть ситуация, когда есть два поля. Field1 и Field2 . Все, что я хочу сделать, это пустое Field1 при изменении Field1 и наоборот. Поэтому в конце только одно поле имеет контент на нем.

 Field1 = (EditText)findViewById(R.id.field1); Field2 = (EditText)findViewById(R.id.field2); Field1.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field2.setText(""); } }); Field2.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field1.setText(""); } }); 

Он отлично работает, если я прикрепляю addTextChangedListener только к Field1 , но когда я делаю это для обоих полей, приложение падает. Очевидно, потому что они пытаются изменить друг друга на неопределенный срок. После того, как Field1 изменяет, он очищает Field2 в этот момент Field2 изменяется, поэтому он очистит Field1 и так далее …

Может ли кто-нибудь предложить какое-либо решение?

Solutions Collecting From Web of "Андроид на прослушивателе изменения текста"

Вы можете добавить проверку, чтобы очистить, только если текст в поле не пуст (т.е. когда длина отличается от 0).

 Field1.addTextChangedListener(new TextWatcher() { @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(s.length() != 0) Field2.setText(""); } }); Field2.addTextChangedListener(new TextWatcher() { @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(s.length() != 0) Field1.setText(""); } }); 

Документация для TextWatcher здесь .

Также, пожалуйста, соблюдайте соглашения об именах .

Я знаю, что это уже давно, но кто-то может когда-нибудь столкнуться с этим.

У меня была аналогичная проблема, в которой я бы назвал setText на EditText, и onTextChanged будет вызываться, когда я этого не хочу. Моим первым решением было написать код после вызова setText (), чтобы отменить урон, причиненный слушателем. Но это было не очень элегантно. После выполнения некоторых исследований и тестирования я обнаружил, что использование getText (). Clear () очищает текст так же, как setText (""), но поскольку он не устанавливает текст, слушатель не вызывается, так что Решил мою проблему. Я переключил все свои вызовы setText ("") на getText (). Clear (), и мне больше не нужны бинты, так что, возможно, это тоже решит вашу проблему.

Попробуй это:

 Field1 = (EditText)findViewById(R.id.field1); Field2 = (EditText)findViewById(R.id.field2); Field1.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field2.getText().clear(); } }); Field2.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field1.getText().clear(); } }); 

Установите флажок String перед тем, как установить другой EditText в пустой. Если Field1 пусто, то зачем нужно снова менять ("")? Поэтому вы можете проверить размер своей строки с помощью s.lenght () или любого другого решения

Другой способ, которым вы можете проверить длину строки:

 String sUsername = Field1.getText().toString(); if (!sUsername.matches("")) { // do your job } 

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

  edt_amnt_sent.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } }); edt_amnt_receive.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } }); 

Объявлено первоначально boolean skipOnChange = false;

Вы также можете использовать метод hasFocus ():

 public void onTextChanged(CharSequence s, int start, int before, int count) { if (Field2.hasfocus()){ Field1.setText(""); } } 

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

Немного поздно ответ, но вот многоразовое решение:

 /** * An extension of TextWatcher which stops further callbacks being called as * a result of a change happening within the callbacks themselves. */ public abstract class EditableTextWatcher implements TextWatcher { private boolean editing; @Override public final void beforeTextChanged(CharSequence s, int start, int count, int after) { if (editing) return; editing = true; try { beforeTextChange(s, start, count, after); } finally { editing = false; } } protected abstract void beforeTextChange(CharSequence s, int start, int count, int after); @Override public final void onTextChanged(CharSequence s, int start, int before, int count) { if (editing) return; editing = true; try { onTextChange(s, start, before, count); } finally { editing = false; } } protected abstract void onTextChange(CharSequence s, int start, int before, int count); @Override public final void afterTextChanged(Editable s) { if (editing) return; editing = true; try { afterTextChange(s); } finally { editing = false; } } public boolean isEditing() { return editing; } protected abstract void afterTextChange(Editable s); } 

Поэтому, когда используется вышеописанное, любые вызовы setText() происходящие в TextWatcher, не приведут к повторному вызову TextWatcher:

 /** * A setText() call in any of the callbacks below will not result in TextWatcher being * called again. */ public class MyTextWatcher extends EditableTextWatcher { @Override protected void beforeTextChange(CharSequence s, int start, int count, int after) { } @Override protected void onTextChange(CharSequence s, int start, int before, int count) { } @Override protected void afterTextChange(Editable s) { } }