Как я могу изменить текст EditText без запуска Text Watcher? - PullRequest
80 голосов
/ 22 февраля 2012

У меня есть поле EditText с надписью Customer Text Watcher. В куске кода мне нужно изменить значение в EditText, которое я делаю, используя .setText("whatever").

Проблема в том, что как только я произвожу это изменение, будет вызван метод afterTextChanged, который создал бесконечный цикл. Как я могу изменить текст без его срабатывания после TextChanged?

Мне нужен текст в методе afterTextChanged, поэтому не рекомендуется удалять TextWatcher.

Ответы [ 13 ]

0 голосов
/ 21 марта 2017

Я создал абстрактный класс, который устраняет циклические проблемы, возникающие при внесении изменений в EditText с помощью TextWatcher.

/**
 * 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;
        }
    }

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

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

    abstract void afterTextChange(Editable s);
}
0 голосов
/ 19 августа 2015

Мой вариант:

public class CustomEditText extends AppCompatEditText{
    TextWatcher l;

    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setOnTextChangeListener(TextWatcher l) {
        try {
            removeTextChangedListener(this.l);
        } catch (Throwable e) {}
        addTextChangedListener(l);
        this.l = l;
    }

    public void setNewText(CharSequence s) {
        final TextWatcher l = this.l;
        setOnTextChangeListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
        setText(s);
        post(new Runnable() {
            @Override
            public void run() {
                setOnTextChangeListener(l);
            }
        });
    }


}

Установить слушателей только с помощью setOnTextChangeListener () и установить текст только с помощью setNewText (я хотел переопределить setText (), но это окончательно)

0 голосов
/ 19 июня 2014

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

Наиболее распространенной ошибкой является установка нового текста в связанном EditText или Editable, даже если текст фактически не изменялся.

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

Поскольку Editable - это интерфейс, вы можете даже использовать его фиктивную реализацию, которая выдает исключение RuntimeException, если вызывается какой-либо из его методов, пытающихся изменить его содержимое, при тестировании содержимого, которое должно быть стабильным.

...