Как изменить текст TextView в DataChange без обратного вызова прослушивателя TextWatcher - PullRequest
9 голосов
/ 15 июня 2011
TextView textView=new TextView(context);
    textView.addTextChangedListener(new TextWatcher() {

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

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            s.append("A");

        }
    });

, если мы добавим TextWatcher к TextView, и я хочу добавить письмо к этому TextView, каждый раз, когда пользователь пишет в нем письмо, но это продолжает вызыватьTextWatcher Слушатель, так что до StackOverFlow error, так как добавить текст без повторного вызова TextWatcher Слушателя?

Ответы [ 4 ]

31 голосов
/ 09 июня 2013

Это просто:

@Override
public void afterTextChanged(Editable s) {
    editText.removeTextChangedListener(this);
    //Any modifications at this point will not be detected by TextWatcher,
    //so no more StackOverflowError 
    s.append("A");
    editText.addTextChangedListener(this);
}
6 голосов
/ 05 марта 2015

Другой способ избежать переполнения стека:

TextView textView=new TextView(context);
    textView.addTextChangedListener(new TextWatcher() {

        boolean editing=false;

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

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (!editing){
               editing=true;
               s.append("A");
               editing=false;
        }


        }
    });
4 голосов
/ 15 июня 2011

Документация afterTextChanged гласит:

Этот метод вызывается, чтобы уведомить вас, что где-то в пределах s текст был изменен.Вполне допустимо вносить дальнейшие изменения в s из этого обратного вызова, , но будьте осторожны, чтобы не попасть в бесконечный цикл, потому что любые внесенные вами изменения приведут к повторному вызову этого метода рекурсивно .(Вам не сказано, где произошло изменение, потому что другие методы afterTextChanged (), возможно, уже внесли другие изменения и сделали недействительными смещения. Но если вам нужно знать здесь, вы можете использовать setSpan(Object, int, int, int) в onTextChanged(CharSequence, int, int, int), чтобы отметить ваше место изатем посмотрите отсюда, где закончился промежуток.

Итак, с каждым s.append("A") вы call afterTextChanged() снова и т. д.

0 голосов
/ 01 ноября 2017

версия Kotlin

editText.addTextChangedListener(object: TextWatcher {
    override fun afterTextChanged(s: Editable?) {
        if (s.toString().isNotBlank()) {

            val formattedValue: String = // Do some formatting

            editText.removeTextChangedListener(this)
            editText.setText(formattedValue)
            editText.setSelection(editText.text.toString().length)
            editText.addTextChangedListener(this)
        }
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

    }

})
...