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


169

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

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

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

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


1
Вам действительно нужно проверять ввод EditText в то же время, когда пользователь печатает? Почему бы вам просто не проверить EditText, как только пользователь нажмет кнопку «Готово»?
— Кристиан

Это именно то, что я хочу: чтобы текст проверялся, когда пользователь нажимает кнопку «Готово» (под кнопкой «Готово» я имею в виду кнопку «Готово» в QWERTY InputManager ... НЕ кнопку отправки формы). За исключением того, что когда я нажимаю кнопку «Готово», фокус остается на последнем элементе формы, и мой метод проверки никогда не срабатывает. Надеюсь, моя формулировка ясна ...
— Стефан

Решение @Cristian - именно то, что я искал, и его можно найти здесь: stackoverflow.com/questions/43013812/…
— LampPost

@Cristian Я немного опаздываю, но я ищу решение, в котором тексты EditText проверяются, пока человек печатает. У меня есть форма для входа / регистрации, и я хочу показывать кнопку «Отправить» только тогда, когда данные формы верны.
— Zonker.in.Geneva

Ответы:


154

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

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

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

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

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


3
Это выглядит именно то, что мне нужно. Я не слышал о TextWatcher (новичок в SDK / API), но я протестирую его и посмотрю, будет ли он вести себя так, как я думаю. Спасибо за информацию!
— Стефан

1
пожалуйста! :) теперь, когда вы проверяете его, не могли бы вы рассказать, как вы собираетесь информировать пользователя о сбое проверки? В настоящее время я ищу лучшие методы для того же.
— Никс

Нихил Патил, я просто использую тост, чтобы пользователь знал, что он сделал что-то не так. Есть ли какая-то причина, почему это не будет эффективным в вашем случае?
— Евгений Симкин

5
Конечно, тост это естественный способ на Android. Но когда на экране имеется значительное количество элементов, требующих проверки, тосты не кажутся правильным выбором (имхо, это раздражает пользователя). Я экспериментировал с TextView.setError () ( developer.android.com). / ссылка / android / widget /…
— Niks

1
Хотя TextWatcher плохо поддерживает, он работает ... вроде!
— Tivie

126

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

4
@fremmedehenvendelser: каждый EditTextIS-ATextView
— Никс

2
потрясающая абстракция и использование абстрактного класса
— Сахер Ахвал

1
@fullmeriffic, скорее всего, вы не инициализировали свой EditText. Убедитесь, что вы звоните addTextChangedListenerпосле разрешения вашего текста редактирования из вида
— Ghostli


2
Принцип сегрегации интерфейса на практике
— Мацей Беймчик

92

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

Скриншот использования setError, взятый у Донна Фелкера, автора связанного поста


Как вы получаете TextWatcher для доступа к двум EditTexts? Я успешно добавил TextWatcher к себе passwordConfirmTextField, но мне нужно сослаться на другой passwordTextField, чтобы я мог сравнить их. Какие-либо предложения?
— Zonker.in.Geneva

26

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


Эта библиотека работает как шарм. Но аннотации @TextRule были удалены из версии 2.0.3?
— LTroya

1
Он был заменен @Lengthаннотацией.
— Рагунатх Джавахар

@RagunathJawahar Я заметил, что проверка не работает, если вы проверяете входящие данные, т.е. контакт, поэтому я пытаюсь проверить электронную почту, которая пришла от Intent -> Contacts, но как только я сосредотачиваюсь на EditText и добавляю / удаляю любой текст, тогда проверка работает как проверка, также вызывается для TextChange, и validate () также вызывается, когда мы получаем данные из Contact.
— Ронак Мехта

11

Это было хорошее решение отсюда

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

как я могу использовать его вместе с пробелом и не ограничивать два пробела рядом друг с другом?
— Чир

10

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


Лучший ответ, но я должен был использовать com.google.android.material.textfield.TextInputLayout(обратите внимание на изменение материала ). Получил это от ответа: stackoverflow.com/a/56753953/900394
— Алаа М.

8

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

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

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

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

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


7

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

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

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


1
Это хорошее решение для вещей, которые можно проверять при вводе (буквенно-цифровой ввод), но оно не будет работать для вещей, которые должны проверяться только после ввода пользователем ввода (адрес электронной почты).
— Питер Айтай

Как бы вы вызвали этот тост? Фильтр предотвращает реакцию любых текстовых наблюдателей ... Возможно, с помощью onKeyListener?
— продолжительность

Я запустил этот Toast с условием IF из метода filter () (в классе InputFilter).
— Moisés

6

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

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

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


5

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

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 : проверяет, содержит ли поле действительную кредитную карту с использованием алгоритма Луна
  • телефон : проверяет, что поле содержит действительный номер телефона
  • имя_домена : проверяет, содержит ли поле допустимое имя домена (всегда проходит тест на уровне API <8)
  • ipAddress : проверяет, что поле содержит действительный IP-адрес
  • webUrl : проверяет, что поле содержит действительный URL (всегда проходит тест на уровне API <8)
  • Дата : проверяет, является ли поле допустимым форматом даты / даты / времени (если установлен customFormat, проверяется с помощью customFormat)
  • НОЧЕК : Он не проверяет ничего, кроме пустоты поля.

2

В файле main.xml

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

Сделай это :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

Вы можете получить желаемое поведение, слушая, когда пользователь нажимает кнопку «Готово» на клавиатуре, а также ознакомьтесь с другими советами по работе с 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;
    }});  

0

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

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

-2

Я создал эту библиотеку для 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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.