Android: Как я могу проверить ввод EditText? - PullRequest
162 голосов
/ 04 мая 2010

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

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

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

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

Ответы [ 14 ]

149 голосов
/ 18 мая 2010

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

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

  1. Ваша деятельность реализует android.text.TextWatcher интерфейс
  2. Вы добавляете слушателей 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

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

РЕДАКТИРОВАТЬ: Для более чистого подхода см. Ответ Кристофера Перри ниже.

116 голосов
/ 07 августа 2012

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 */
    }
});
88 голосов
/ 24 ноября 2011

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

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

24 голосов
/ 23 октября 2012

Чтобы уменьшить детализацию логики проверки, я создал библиотеку для 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.

11 голосов
/ 14 августа 2012

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

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}); 
9 голосов
/ 25 июля 2015

Обновленный подход - 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 репозитория , зацените пример, если хотите!

7 голосов
/ 25 мая 2012

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

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

  1. альфа
  2. буквенно-цифровой
  3. цифровая
  4. универсальное регулярное выражение
  5. пустота строки

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

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

7 голосов
/ 05 октября 2011

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

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

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

6 голосов
/ 02 января 2011

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

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

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

5 голосов
/ 18 декабря 2013

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

EditText Validator

    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.
    }
}

пользовательских валидаторов плюс встроенные:

  • регулярное выражение : для пользовательского регулярного выражения
  • числовой : только для числового поля
  • альфа : для альфа-поля
  • буквенно-цифровой : угадайте, что?
  • personName : проверяет, является ли введенный текст именем или фамилией человека.
  • personFullName : проверяет, является ли введенное значение полным полным именем.
  • email : проверяет, является ли поле действительным адресом электронной почты
  • creditCard : проверяет, содержит ли поле действительную кредитную карту, используя алгоритм Луна
  • phone : проверяет наличие в поле действительного номера телефона
  • имя_домена : проверяет, содержит ли поле допустимое имя домена (всегда проходит тест на уровне API <8) </li>
  • ipAddress : проверяет, содержит ли поле действительный IP-адрес
  • webUrl : проверяет, содержит ли поле действительный URL (всегда проходит тест на уровне API <8) </li>
  • date : проверяет, является ли поле допустимым форматом даты / даты / времени (если установлен customFormat, проверяется с помощью customFormat)
  • nocheck : Он не проверяет ничего, кроме пустоты поля.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...