EditText.setText() / getText(), по-видимому, слишком медленный для использования в TextWatcher

#android

#Android

Вопрос:

У меня есть TextWatcher, который добавляет знак доллара перед значением EditText (это поле цены). Все работает нормально, за исключением того, что если вы наберете две первые цифры достаточно быстро, вторая цифра не появится. Как только вы пройдете первые две цифры, все будет в порядке. Если вы вводите их медленно (почти секунду между ними), это также работает нормально. Вот код TextWatcher, который я использую:

 @AfterTextChange(R.id.add_itemPrice) // android annotations way
void addDollar(Editable e) {
    if (priceFieldBeingModified) {
        return;
    }
    if (!e.toString().startsWith(CURRENCY_SYMB)) {
        priceFieldBeingModified = true;
        String newValue = CURRENCY_SYMB   e;
        priceField.setText(newValue);
        if (priceField.getSelectionStart() == 0) {
            // move the cursor to the end
            priceField.setSelection(priceField.getText().length());
        }
        priceFieldBeingModified = false;
    }
}
  

В priceField EditText исправлена layout_width / layout_height (в dp). Из того, что я могу собрать, setText() / getText() просто слишком дороги, но я не знаю, как их избежать в этом случае.
priceField.getText().insert(0, CURRENCY_SYMB) по какой-то причине ничего не делает.

РЕДАКТИРОВАТЬ: Похоже, проблема возникает только на Android 4.3 (или телефоне Xperia Z). Попробовал телефон 4.1 — работает как шарм.

Любые предложения будут оценены, у меня нет идей с этим!

Комментарии:

1. Что касается вашей последней попытки: priceField.getText() автоматически не обновляет EditText, если вы измените строку, которую вы получаете из getText() . Для этого вам нужно setText() .

2. хорошо, верно. К сожалению, insert() не перемещает курсор автоматически, как я надеялся, так что это ничего не меняет.

3. Пытался отключить фильтр в этом поле — не помогло. Начал отчаиваться, попробовал тот же код, что и у меня, без аннотаций Android — тоже не повезло 🙂

Ответ №1:

Для меня это работает нормально:

 @Override
public void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub
    if(s.toString().equalsIgnoreCase(""))
    {

    }

    else if (!s.toString().startsWith("$")) {
        priceFieldBeingModified = true;
        String newValue = "$"   s;
        e.setText(newValue);
        if (e.getSelectionStart() == 0) {
        // move the cursor to the end
        e.setSelection(e.getText().length());
    }
    priceFieldBeingModified = false;
}
  

Он проверяет, не является ли строка null и не начинается с «$», затем добавляет «$» в начале и перемещает курсор в конец.

Комментарии:

1. Единственное значимое отличие от моего кода в том, что проверка редактируемого является пустой в начале? Или я чего-то не хватает?

2. priceField.setText(newValue); заменяется на e.setText(newValue); . Вы пробовали это? Я проверяю null, чтобы он не добавлял $ при очистке edittext. @Leo протестируйте один раз. Я тестировал

3. это мой EditText, @ThaMe90

4. priceField — это мой EditText, то есть такой же, как ваш «e». Итак, никаких изменений?

5. Тогда вы, должно быть, совершаете какую-то другую ошибку, поскольку это отлично работает для меня @Leo, Всего наилучшего, чтобы разобраться в этом 🙂