Android: проверка EditText с помощью TextWatcher и .setError()

Я реализовал простую проверку для TextEdit, используя этот код:

    title = (EditText) findViewById(R.id.title);
    title.addTextChangedListener(new TextWatcher() {

        @Override
        public void afterTextChanged(Editable s) {
             if (title.getText().length() < 1) {
                    title.setError( "Title is required" );
               } else {
                    title.setError(null); 
               }
            
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            // TODO Auto-generated method stub
            
        }
    });

Функция проверяет, вставлен ли какой-либо текст в textchange, и все работает отлично, пока я не поставлю курсор в уже пустое поле заголовка и не нажму еще раз удалить. сообщение об ошибке сбрасывается, и textwatcher не вызывается, потому что текст не изменяется. Как я могу даже отобразить сообщение об ошибке в этом случае?


person Lut Ze    schedule 12.11.2012    source источник
comment
наблюдатель за текстом вызывается. Но в уже пустом текстовом поле, если вы нажмете клавишу удаления, обратите внимание, что текст не изменяется, и поэтому afterTextChanged не будет вызываться.   -  person Robin Chander    schedule 12.11.2012
comment
Решение найдено! Смотрите мой ответ ниже.   -  person Oleg Vaskevich    schedule 21.12.2012


Ответы (2)


Вы также должны иметь возможность переопределить метод onKeyUp (http://developer.android.com/reference/android/view/KeyEvent.Callback.html). Там проверьте, была ли нажата клавиша KeyEvent.KEYCODE_DEL, а затем проверьте, не пуст ли текст в EditText. Если это так, скиньте свою ошибку.

person Matt McHugh    schedule 12.11.2012
comment
Хорошее предложение, но KeyEvents не рекомендуется для мягкого ввода. нет гарантии, что любое нажатие клавиши на программной клавиатуре будет генерировать событие клавиши, это оставлено на усмотрение IME, программная клавиатура по умолчанию никогда не будет отправлять какие-либо события клавиш любому приложению, предназначенному для Jelly Bean или более поздней версии, и будет отправлять только события для НЕКОТОРЫХ нажатий клавиш удаления и возврата к приложениям, предназначенным для Ice Cream Sandwich или более ранней версии разработчика .android.com/reference/android/view/KeyEvent.html - person Robin Chander; 12.11.2012
comment
Интересно, я такого не видел. Если это так, я не совсем уверен, что ОП сможет добиться того, чего хочет. - person Matt McHugh; 12.11.2012
comment
жаль, но спасибо за попытку! я сдался и просто реализовал простую проверку при отправке... - person Lut Ze; 06.12.2012

Кажется, что внутри TextView есть флаг, и он вызывает setError(null), если клавиатура отправляет ключевую команду, но текст остается прежним. Поэтому я создал подкласс EditText и реализовал onKeyPreIme(), чтобы проглотить клавишу удаления, если текст "". Просто используйте EditTextErrorFixed в своих файлах XML:

package android.widget;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;

public class EditTextErrorFixed extends EditText {
    public EditTextErrorFixed(Context context) {
        super(context);
    }

    public EditTextErrorFixed(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextErrorFixed(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * Don't send delete key so edit text doesn't capture it and close error
     */
    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (TextUtils.isEmpty(getText().toString()) && keyCode == KeyEvent.KEYCODE_DEL)
            return true;
        else
            return super.onKeyPreIme(keyCode, event);
    }
}
person Oleg Vaskevich    schedule 21.12.2012