Изменение текста в Android при изменении текста вызывает ошибку переполнения - PullRequest
8 голосов
/ 28 августа 2011

Я хочу создать приложение, которое может преобразовывать текст, который пользователь вводит в виджет EditText в режиме реального времени, и я добавил TextWatcher, чтобы позволить мне что-то делать при изменении текста, но это вызывает переполнение ошибка, потому что я в основном создаю бесконечный цикл (onTextChange -> code to change text -> onTextChange -> etc...).

Кто-нибудь получил представление о том, как обойти эту проблему?

Вот пример

private boolean isEditable = true;
private EditText text;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    text = (EditText) findViewById(R.id.editText1);
    text.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 (isEditable) {
                isEditable = false;
                styleText(s.toString());
            } else {
                isEditable = true;
            }
        }

    });

}

private void styleText(String completeText) {
    text.setText(completeText + " test");
}

И хотя вышеприведенное, похоже, действительно работает, я не могу заставить его работать с Html.fromHtml();, что я и собираюсь использовать.

отредактировано снова

public class Main extends Activity implements TextWatcher {

    private EditText text;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        text = (EditText) findViewById(R.id.editText1);
        text.addTextChangedListener(this);
    }

    @Override
    public void afterTextChanged(Editable s) {
        text.removeTextChangedListener(this);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        text.addTextChangedListener(this);
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        text.removeTextChangedListener(this);
        text.setText("Test!");
    }
}

Это выбрасывает StackOverflowException в строке 37, которая "text.setText("Test!");"

Ответы [ 2 ]

25 голосов
/ 28 августа 2011

РЕДАКТИРОВАТЬ: И работает, исключение не выбрасывается:

  txtwt = new TextWatcher(){

            @Override
            public void afterTextChanged(Editable s) {

            Log.i("REACHES AFTER", "YES");

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                Log.i("REACHES BEFORE", "YES");
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                text.removeTextChangedListener(txtwt);//after this line you do the editing code 
                text.setText("TEST");
                Log.i("REACHES ON", "YES");
                text.addTextChangedListener(txtwt); // you register again for listener callbacks

            }};
       text = (EditText) findViewById(R.id.editText1);
        text.addTextChangedListener(txtwt);

Это доказательство Logcat, когда я резко нажимаю клавиши:

08-28 19:53:21.265: INFO/REACHES BEFORE(492): YES
08-28 19:53:21.276: INFO/REACHES ON(492): YES
08-28 19:53:21.276: INFO/REACHES AFTER(492): YES
08-28 19:53:21.296: INFO/REACHES BEFORE(492): YES
08-28 19:53:21.305: INFO/REACHES ON(492): YES
08-28 19:53:21.305: INFO/REACHES AFTER(492): YES
08-28 19:53:21.745: INFO/REACHES BEFORE(492): YES
08-28 19:53:21.755: INFO/REACHES ON(492): YES
08-28 19:53:21.755: INFO/REACHES AFTER(492): YES
08-28 19:53:21.775: INFO/REACHES BEFORE(492): YES
08-28 19:53:21.785: INFO/REACHES ON(492): YES
08-28 19:53:21.785: INFO/REACHES AFTER(492): YES
08-28 19:53:22.698: INFO/REACHES BEFORE(492): YES
08-28 19:53:22.705: INFO/REACHES ON(492): YES
08-28 19:53:22.705: INFO/REACHES AFTER(492): YES
08-28 19:53:23.855: INFO/REACHES BEFORE(492): YES
08-28 19:53:23.865: INFO/REACHES ON(492): YES
08-28 19:53:23.865: INFO/REACHES AFTER(492): YES
08-28 19:53:24.385: INFO/REACHES BEFORE(492): YES
08-28 19:53:24.395: INFO/REACHES ON(492): YES
08-28 19:53:24.395: INFO/REACHES AFTER(492): YES
08-28 19:53:24.485: INFO/REACHES BEFORE(492): YES
08-28 19:53:24.485: INFO/REACHES ON(492): YES
08-28 19:53:24.485: INFO/REACHES AFTER(492): YES
08-28 19:53:24.515: INFO/REACHES BEFORE(492): YES
08-28 19:53:24.525: INFO/REACHES ON(492): YES
08-28 19:53:24.525: INFO/REACHES AFTER(492): YES
08-28 19:53:24.625: INFO/REACHES BEFORE(492): YES
08-28 19:53:24.635: INFO/REACHES ON(492): YES
08-28 19:53:24.635: INFO/REACHES AFTER(492): YES
08-28 19:53:24.654: INFO/REACHES BEFORE(492): YES
08-28 19:53:24.665: INFO/REACHES ON(492): YES
08-28 19:53:24.665: INFO/REACHES AFTER(492): YES
6 голосов
/ 28 августа 2011
private String originalValue;
void onTextChanged(CharSequence text, int start, int before, int after) {
   if (text.toString().equals(originalValue)) {
      // do nothing
   } else {
      //change your text
      originalValue = text.toString();
   }
}

Отредактировано:

public void onTextChanged(CharSequence s, int start, int before, int count) {
       String currentText = s.toString();
       if (currentText.equals(originalValue)) { //the originalValue must be defined outside of the Watcher
          originalValue = styleText(currentText);
          // text.setText(originalValue); //if styleText doesn't do this
       } else {
          return;
       }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...