Android на слушателя изменения текста
у меня есть ситуация, когда есть два поля. field1 и field2. Все, что я хочу
делать пусто field2, когда 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 и так далее...
может ли кто-нибудь предложить какое-либо решение?
7 ответов:
вы можете добавить проверку, чтобы очистить только тогда, когда текст в поле не пуст (т. е. когда длина отличается от 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().ясно () и мне больше не нужны бинты, так что, возможно, это тоже решит вашу проблему.
попробуйте это:
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(); } });
немного поздно ответа, но вот многоразовое решение:
/** * 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) { } }
проверьте строку перед установкой другой
EditTextпустое. еслиField1пусто тогда зачем нужно снова менять на ( "")? таким образом, вы можете проверить размер вашей строки с ы.длина() или любое другое решениедругой способ, которым вы можете проверить длину строки:
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; } } });объявленный изначально логический skipOnChange = false;
Если вы используете Kotlin для разработки Android, то вы можете добавить текст изменения слушателя с помощью этого кода:
myTextField.addTextChangedListener(object : TextWatcher{ override fun afterTextChanged(s: Editable?) {} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} })
вы также можете использовать метод hasFocus ():
public void onTextChanged(CharSequence s, int start, int before, int count) { if (Field2.hasfocus()){ Field1.setText(""); } }протестировал это для задания колледжа, над которым я работал, чтобы преобразовать температурные шкалы, когда пользователь вводил их. Работал отлично, и это намного проще.
Comments