Android: EditText Validation with TextWatcher and

2019-01-20 06:24发布

问题:

i have implemented a simple validation for an TextEdit, using this code:

    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

        }
    });

The funcion checks, if there is any text inserted on a textchange and everything works perfectly, unless when i put my cursor in the already empty title field, and press delete once more. the error message gets resetted and the textwatcher is not called, because there is no text change. How can i even display the error message in this case?

回答1:

You should be able to also override the onKeyUp method (http://developer.android.com/reference/android/view/KeyEvent.Callback.html). In there, check to see if the key pressed was KeyEvent.KEYCODE_DEL, then also check to see if the text in the EditText is empty. If it is, throw your error.



回答2:

It seems that internally TextView has a flag and calls setError(null) if the keyboard sends a key command but the text remains the same. So I subclassed EditText and implemented onKeyPreIme() to swallow the delete key if the text is "". Just use EditTextErrorFixed in your XML files:

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);
    }
}