Android: Как я могу проверить ввод EditText?

Мне нужно сделать проверку ввода формы в серии EditTexts. Я использую OnFocusChangeListeners для запуска проверки после того, как пользователь вводит в каждый из них, но это не ведет себя так, как требуется для последнего EditText.

Если я нажимаю кнопку "Готово" при вводе в окончательный EditText, то InputMethod отключается, но технически фокус никогда не теряется на EditText (и поэтому проверка не происходит).

Какое лучшее решение?

Должен ли я отслеживать, когда InputMethod отключается от каждого EditText, а не при изменении фокуса? Если да, то как?

Ответ 1

Почему вы не используете TextWatcher?

Поскольку у вас есть количество ящиков EditText для проверки, я думаю, вам понравится следующее:

  • Ваша деятельность реализует интерфейс android.text.TextWatcher
  • Вы добавляете слушателей TextChanged к вам. Окна EditText.
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
  1. Из переопределенных методов вы можете использовать метод afterTextChanged(Editable s) следующим образом
@Override
public void afterTextChanged(Editable s) {
    // validation code goes here
}

Editable s не помогает найти, какой текст в тексте EditText будет изменен. Но вы можете напрямую проверить содержимое полей EditText, например

String txt1String = txt1.getText().toString();
// Validate txt1String

в том же методе. Надеюсь, я поняла, и если да, то это помогает!:)

EDIT: Для более чистого подхода см. ответ Кристофера Перри ниже.

Ответ 2

TextWatcher немного подробен для моего вкуса, поэтому я сделал что-то немного легче глотать:

public abstract class TextValidator implements TextWatcher {
    private final TextView textView;

    public TextValidator(TextView textView) {
        this.textView = textView;
    }

    public abstract void validate(TextView textView, String text);

    @Override
    final public void afterTextChanged(Editable s) {
        String text = textView.getText().toString();
        validate(textView, text);
    }

    @Override
    final public void beforeTextChanged(CharSequence s, int start, int count, int after) { /* Don't care */ }

    @Override
    final public void onTextChanged(CharSequence s, int start, int before, int count) { /* Don't care */ }
}

Просто используйте его так:

editText.addTextChangedListener(new TextValidator(editText) {
    @Override public void validate(TextView textView, String text) {
       /* Validation code here */
    }
});

Ответ 3

Если вы хотите получить хорошие всплывающие окна и изображения при возникновении ошибки, вы можете использовать метод setError класса EditText, как я описываю здесь

Screenshot of the use of setError taken from Donn Felker, the author of the linked post

Ответ 4

Чтобы уменьшить многословие логики проверки, я создал библиотеку для Android. Он выполняет большую часть ежедневных проверок, используя аннотации и встроенные правила. Существуют ограничения, такие как @TextRule, @NumberRule, @Required, @Regex, @Email, @IpAddress, @Password и т.д.,

Вы можете добавить эти аннотации к ссылкам на виджеты пользовательского интерфейса и выполнить проверки. Он также позволяет асинхронно выполнять проверки, которые идеально подходят для ситуаций, таких как проверка уникального имени пользователя с удаленного сервера.

На домашней странице проекта связанный пост в блоге, где я написал примеры кода о том, как писать пользовательские правила для валидации.

Вот простой пример, иллюстрирующий использование библиотеки.

@Required(order = 1)
@Email(order = 2)
private EditText emailEditText;

@Password(order = 3)
@TextRule(order = 4, minLength = 6, message = "Enter at least 6 characters.")
private EditText passwordEditText;

@ConfirmPassword(order = 5)
private EditText confirmPasswordEditText;

@Checked(order = 6, message = "You must agree to the terms.")
private CheckBox iAgreeCheckBox;

Библиотека расширяема, вы можете написать свои собственные правила, расширив класс Rule.

Ответ 5

Это было приятное решение от здесь

InputFilter filter= new InputFilter() { 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
        for (int i = start; i < end; i++) { 
            String checkMe = String.valueOf(source.charAt(i));

            Pattern pattern = Pattern.compile("[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789_]*");
            Matcher matcher = pattern.matcher(checkMe);
            boolean valid = matcher.matches();
            if(!valid){
                Log.d("", "invalid");
                return "";
            }
        } 
        return null; 
    } 
};

edit.setFilters(new InputFilter[]{filter}); 

Ответ 6

Я считаю InputFilter более подходящим для проверки ввода текста на Android.

Вот простой пример: Как использовать InputFilter для ограничения символов в EditText на Android?

Вы можете добавить Toast для обратной связи с пользователем о ваших ограничениях. Также проверьте, нет ли андроида: inputType.

Ответ 7

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

Текущий, как я пишу, изначально, поддерживаемый с помощью xml-атрибутов:

  • альфа
  • alpha numeric
  • Числовое
  • общее регулярное выражение
  • пустота строки

Вы можете проверить это здесь

Надеюсь, вам понравится:)

Ответ 8

Обновленный подход - TextInputLayout:

Недавно Google запустила библиотеку поддержки дизайна, и есть один компонент, называемый TextInputLayout, и он поддерживает отображение ошибки с помощью setErrorEnabled(boolean) и setError(CharSequence).

Как это использовать?

Шаг 1: Оберните свой EditText с помощью TextInputLayout:

  <android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/layoutUserName">

    <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="hint"
      android:id="@+id/editText1" />

  </android.support.design.widget.TextInputLayout>

Шаг 2. Проверка ввода

// validating input on a button click
public void btnValidateInputClick(View view) {

    final TextInputLayout layoutUserName = (TextInputLayout) findViewById(R.id.layoutUserName);
    String strUsername = layoutLastName.getEditText().getText().toString();

    if(!TextUtils.isEmpty(strLastName)) {
        Snackbar.make(view, strUsername, Snackbar.LENGTH_SHORT).show();
        layoutUserName.setErrorEnabled(false);
    } else {
        layoutUserName.setError("Input required");
        layoutUserName.setErrorEnabled(true);
    }
}

Я создал пример над моим репозиторием Github, проверьте пример, если хотите!

Ответ 9

Мне нужно было провести проверку внутри поля, а не проверку между полями, чтобы проверить, что мои значения были беззнаковыми значениями с плавающей запятой в одном случае и знаками с плавающей запятой в другой. Вот что мне кажется:

    <EditText
        android:id="@+id/x" 
        android:background="@android:drawable/editbox_background" 
        android:gravity="right" 
        android:inputType="numberSigned|numberDecimal" 
    />

Обратите внимание: у вас не должно быть пробелов внутри "numberSigned | numberDecimal". Например: "numberSigned | numberDecimal" не будет работать. Я не знаю, почему.

Ответ 10

Это выглядит действительно многообещающим, и именно то, что заказал мне документ:

Валидатор EditText

    public void onClickNext(View v) {
    FormEditText[] allFields    = { etFirstname, etLastname, etAddress, etZipcode, etCity };


    boolean allValid = true;
    for (FormEditText field: allFields) {
        allValid = field.testValidity() && allValid;
    }

    if (allValid) {
        // YAY
    } else {
        // EditText are going to appear with an exclamation mark and an explicative message.
    }
}

настраиваемые валидаторы, а также встроенные функции:

  • regexp: для пользовательского регулярного выражения
  • число: только для числового поля
  • alpha: для поля только альфа
  • alphaNumeric: угадайте, что?
  • personName: проверяет, является ли введенный текст персоной первой или последней фамилии.
  • personFullName: проверяет, является ли введенное значение полным полным именем.
  • электронная почта: проверяет правильность поля в поле
  • creditCard: проверяет, что поле содержит действительную кредитную карту, используя алгоритм Луна
  • телефон: проверяет, что поле содержит действительный номер телефона
  • domainName: проверяет, что это поле содержит допустимое имя домена (всегда проходит тест на уровне API < 8)
  • ipAddress: проверяет, что поле содержит допустимый IP-адрес
  • webUrl: проверяет, что поле содержит действительный url (всегда проходит тест на уровне API < 8)
  • date: проверяет, что поле является допустимым форматом date/datetime (если установлен customFormat, проверяется с помощью customFormat)
  • nocheck: он не проверяет ничего, кроме пустоты поля.

Ответ 11

Вы можете получить желаемое поведение, слушая, когда пользователь нажимает кнопку "Готово" на клавиатуре, а также выдает другие советы о работе с EditText в моем сообщении "Проверка формы Android - правильный путь"

Пример кода:

mTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {                    
            validateAndSubmit();
            return true;
        }
        return false;
    }});  

Ответ 12

В файле main.xml

Вы можете поместить следующий attrubute для проверки только символа алфавита, который может принимать в edittext.

Сделайте это:

  android:entries="abcdefghijklmnopqrstuvwxyz"

Ответ 13

для проверки подлинности электронной почты и пароля

  if (isValidEmail(et_regemail.getText().toString())&&etpass1.getText().toString().length()>7){
      if (validatePassword(etpass1.getText().toString())) {
      Toast.makeText(getApplicationContext(),"Go Ahead".....
      }
      else{

       Toast.makeText(getApplicationContext(),"InvalidPassword".....
       }

}else{

 Toast.makeText(getApplicationContext(),"Invalid Email".....
}


public boolean validatePassword(final String password){
    Pattern pattern;
    Matcher matcher;
    final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[A-Z])(?=.* 
    [@#$%^&+=!])(?=\\S+$).{4,}$";
    pattern = Pattern.compile(PASSWORD_PATTERN);
    matcher = pattern.matcher(password);

    return matcher.matches();
}

public final static boolean isValidEmail(CharSequence target) {
    if (target == null)
        return false;

    return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}

Ответ 14

Я создал эту библиотеку для android, где вы можете легко проверить конструкцию материалов EditText внутри и EditTextLayout следующим образом:

    compile 'com.github.TeleClinic:SmartEditText:0.1.0'

то вы можете использовать его следующим образом:

<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
    android:id="@+id/passwordSmartEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:setLabel="Password"
    app:setMandatoryErrorMsg="Mandatory field"
    app:setPasswordField="true"
    app:setRegexErrorMsg="Weak password"
    app:setRegexType="MEDIUM_PASSWORD_VALIDATION" />

<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
    android:id="@+id/ageSmartEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:setLabel="Age"
    app:setMandatoryErrorMsg="Mandatory field"
    app:setRegexErrorMsg="Is that really your age :D?"
    app:setRegexString=".*\\d.*" />

Затем вы можете проверить, действительно ли это так:

    ageSmartEditText.check()

Для получения дополнительных примеров и настройки проверьте репозиторий https://github.com/TeleClinic/SmartEditText