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

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

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

Niks
источник
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
1
@StephaneEybert Это анонимный класс
Кристофер Перри
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» не будет работать. Я не уверен почему.

user405821
источник
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)
  • НОЧЕК : Он не проверяет ничего, кроме пустоты поля.
Abs
источник
2

В файле main.xml

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

Сделай это :

  android:entries="abcdefghijklmnopqrstuvwxyz"
KKumar
источник
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.

Karim
источник