TextWatcher afterTextChanged вызывает переполнение стека в Android - PullRequest
5 голосов
/ 25 декабря 2011

У меня есть метод drawItems(), который каждый раз создает новый макет и устанавливает его как contentView.И у меня также есть элемент управления EditText, который должен удалять другие элементы при изменении содержимого.

edit.addTextChangedListener(new TextWatcher() {

                    public void afterTextChanged(Editable s) {
                        currentText = s.toString();
                        drawItems();
                    }

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

                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {
                    }
                });

Я хочу сохранить текущий текст, удалить все элементы и оставить только этот EditText с saved string.Когда я пытаюсь запустить это приложение, возникает ошибка StackOverflow, потому что метод drawItems рендерится бесконечное число раз.Почему он отображает drawItems в afterTextChanged, даже если я не изменяю его содержимое?Он отображается даже до загрузки всей страницы.

Ответы [ 3 ]

3 голосов
/ 25 декабря 2011

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

положить:

public void afterTextChanged(Editable s) {
    if (MyEditText.getText().toString().compareTo(s.toString()) != 0)
    {
        // your code ...
    }
}
2 голосов
/ 24 октября 2015

Этот небольшой фрагмент может помочь:

editText.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) {

                idAnswerEditText.removeTextChangedListener(this);

                String someString = StringUtil.doSomething(s.toString());
                idAnswerEditText.getText().clear();
                idAnswerEditText.getText().append(someString);
                idAnswerEditText.setSelection(someString.length());

                idAnswerEditText.addTextChangedListener(this);

            }

});

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

1 голос
/ 25 декабря 2011

Как сказал @ DroidIn.net в комментарии, вы, вероятно, вызываете событие изменения текста в вашей обработке afterTextChanged - возможно, в drawItems ().

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

...