У меня есть EditText
поле с наблюдателем за текстом клиента. В фрагменте кода мне нужно изменить значение в EditText, которое я использую .setText("whatever")
.
Проблема в том, что как только я вношу это изменение, вызывается afterTextChanged
метод, который создает бесконечный цикл. Как я могу изменить текст, не вызывая afterTextChanged?
Мне нужен текст в методе afterTextChanged, поэтому не предлагайте удалять TextWatcher
.
java
android
event-handling
infinite-loop
user1143767
источник
источник
Короткий ответ
Вы можете проверить, какое представление в настоящее время имеет фокус, чтобы различать события, запускаемые пользователем и программой.
Длинный ответ
В дополнение к короткому ответу: если вы
myEditText
уже имеете фокус, когда вы программно изменяете текст, который вы должны вызватьclearFocus()
, вы звоните,setText(...)
а после повторно запрашиваете фокус. Было бы неплохо поместить это в служебную функцию:Для Котлина:
Поскольку Kotlin поддерживает функции расширения, ваша служебная функция может выглядеть так:
источник
getActivity().getCurrentFocus()
и котлинеactivity?.currentFocus
hasFocus()
прямо по адресуEditText
.Использование:
Вы можете почувствовать небольшую задержку при быстром вводе текста, если вы используете editText.setText () вместо editable.replace () .
источник
Легкий трюк для исправления ... пока ваша логика для получения нового текстового значения редактирования идемпотентна (что, вероятно, было бы, но просто говорило). В вашем методе прослушивателя изменяйте текст редактирования только в том случае, если текущее значение отличается от последнего изменения значения.
например,
источник
setText()
и повторно добавить его после.Вы можете использовать синтаксис Kotlin DSL, чтобы получить универсальное решение для этого:
А внутри TextWatcher вы можете использовать его как:
источник
Я использую так:
И каждый раз, когда вам нужно изменить текст программно, сначала снимайте фокус
источник
Это хорошо работает для меня
источник
Проблема может быть легко решена с помощью
tag
filed, и вам даже не придется иметь дело с фокусом editText.Программная установка текста и тега
Проверка
tag
onTextChangedисточник
Если вам нужно сосредоточиться на
EditText
тексте изменений, вы можете запросить фокус:источник
попробуйте такую логику: я хотел setText (""), не заходя в бесконечный цикл, и этот код у меня работает. Надеюсь, вы сможете изменить это в соответствии со своими требованиями
источник
Вот удобный класс, который предоставляет более простой интерфейс, чем TextWatcher, для обычного случая, когда вы хотите видеть изменения по мере их появления. Это также позволяет игнорировать следующее изменение по запросу OP.
Используйте это так:
Всякий раз, когда вы хотите изменить содержимое,
editText
не вызывая каскада рекурсивных изменений, сделайте следующее:источник
Мой вариант:
Установите слушателей только с помощью setOnTextChangeListener () и установите текст только с помощью setNewText (я хотел переопределить setText (), но это окончательно)
источник
Я создал абстрактный класс, который устраняет циклическую проблему, когда изменение EditText выполняется через TextWatcher.
источник
Очень просто, установите текст с помощью этого метода
источник
Вы должны убедиться, что ваша реализация изменений текста стабильна и не изменяет текст, если никаких изменений не требуется. Обычно это любой контент, который однажды уже прошел через наблюдатель.
Наиболее распространенная ошибка - установить новый текст в связанном EditText или Editable, даже если текст фактически не изменялся.
Вдобавок ко всему, если вы вносите изменения в Editable вместо какого-либо определенного View, вы можете легко повторно использовать свой наблюдатель, а также вы можете протестировать его изолированно с помощью некоторых модульных тестов, чтобы убедиться, что он дает желаемый результат.
Поскольку Editable - это интерфейс, вы даже можете использовать его фиктивную реализацию, которая генерирует исключение RuntimeException, если вызывается какой-либо из его методов, пытающихся изменить его содержимое, при тестировании содержимого, которое должно быть стабильным.
источник
Мой способ сделать это:
В сегменте записи
Слушатель
Все равно работает.
источник