Android: Як я можу перевірити введення EditText?


169

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

Якщо я натискаю кнопку "Готово" під час введення в остаточний EditText, то InputMethod відключається, але технічно фокус ніколи не втрачається на EditText (і тому перевірка ніколи не відбувається).

Яке найкраще рішення?

Чи слід мені контролювати, коли InputMethod від’єднує від кожного EditText, а не коли фокус змінюється? Якщо так, то як?


1
Вам дійсно потрібно перевірити введення EditText одночасно, коли користувач вводить текст? Чому ви не просто перевірите EditText, коли користувач натисне кнопку Готово?
Крістіан

Саме цього я хочу: щоб текст був підтверджений, коли користувач натискає кнопку Готово (під кнопкою Готово я маю на увазі кнопку "Готово" на QWERTY InputManager ... НЕ кнопку подання форми). За винятком того, що коли я натискаю кнопку Готово, фокус залишається на останньому елементі форми, і мій метод перевірки ніколи не запускається. Сподіваюся, моя редакція зрозуміла ...
Стефан

@Cristian рішення «s це саме те , що я шукав і знайшов тут: stackoverflow.com/questions/43013812 / ...
ліхтарний

@ Cristian Приходжу трохи пізно, але я шукаю рішення, де EditText перевіряються, поки людина набирає текст. У мене є форма для входу / реєстрації, і я хочу показувати кнопку "Надіслати" лише тоді, коли дані форми дійсні.
Zonker.in.Geneva

Відповіді:


154

Чому ви не використовуєте 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

тим же методом. Я сподіваюся, що я зрозумів, і якщо я є, це допомагає! :)

EDIT: Для більш чіткого підходу зверніться до відповіді Крістофера Перрі нижче.


3
Це виглядає саме те, що мені потрібно. Я не чув про TextWatcher (новий для SDK / API), але я перевірю його і побачу, чи поводиться він так, як я думаю, що це буде. Дякую за інформацію!
Стефан

1
Ласкаво просимо! :) Тепер, коли ви це підтверджуєте, чи можете ви поділитися тим, як ви збираєтесь повідомити користувача про помилку перевірки? Зараз я шукаю найкращі методи для того ж.
Нікс

Nikhil Patil, я просто використовую Toast, щоб повідомити користувачеві, що вони зробили щось не так. Чи є якась причина, чому це не буде ефективним у вашому випадку?
Євгеній Сімкін

5
Звичайно, тост - це природний спосіб на андроїд. Але коли у нас на екрані є значна кількість елементів, які потребують перевірки, тости, здається, не є правильним вибором. (IMHO, це буде дратувати користувача) Я експериментував з TextView.setError () ( developer.android.com / довідка / андроїд / віджет /…
Нікс

1
Хоча у TextWatcher недостатня підтримка, вона працює ... якось!
Тів'є

125

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
Принцип сегрегації інтерфейсу на практиці
Maciej Beimcik

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 Я зазначив, що перевірка не працює, якщо ви перевіряєте вхідні дані, тобто контакт, тому я намагаюся перевірити електронну пошту, що надійшла з наміру -> контакти, але як тільки я зосереджуюсь на EditText і додаю / видаляю будь-який текст, а потім перевірку працює як перевірка також викликається TextChange, а валідація () також викликається, коли ми отримуємо дані від контакту.
Ronak Mehta

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
Alaa M.

8

Я написав клас, який розширює EditText, який в основному підтримує деякі методи перевірки і насправді дуже гнучкий.

В даний час, як я пишу, спочатку підтримується з допомогою XML - атрибутів методи перевірки є:

  1. альфа
  2. альфа числовий
  3. числовий
  4. родовий регепс
  5. пустота рядка

Ви можете перевірити це тут

Сподіваюся, вам сподобається :)


7

Я вважаю, що InputFilter є більш підходящим для перевірки введення тексту на Android.

Ось простий приклад: як я можу використовувати InputFilter для обмеження символів у EditText в Android?

Ви можете додати тост, щоб відгуки користувача про ваші обмеження. Також перевірте тег Android: inputType.


1
Це хороше рішення для речей, які можна перевірити під час введення (альфа-числовий ввід), але це не буде працювати для речей, які повинні бути перевірені лише після того, як користувач виконає введення даних (адреса електронної пошти).
Пітер Айтай

Як би ви викликали тост? Фільтр запобігає реакції будь-яких спостерігачів тексту ... Можливо, з onKeyListener?
проміжок

Я запустив, що Toast із умовою IF із методу filter () (у класі InputFilter).
Мойсе

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

    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 : для спеціальних
  • числовий : для лише числового поля
  • альфа : для поля, що містить лише альфа
  • alphaNumeric : вгадайте, що?
  • personName : перевіряє, чи введений текст є ім'ям чи прізвищем людини.
  • personFullName : перевіряє, чи введене значення є повним повним ім'ям.
  • електронна пошта : перевіряє, чи є поле дійсним електронною поштою
  • CreditCard : перевіряє, чи містить поле дійсна кредитна картка за допомогою алгоритму Луна
  • телефон : перевіряє, чи містить поле дійсний номер телефону
  • domainName : перевіряє, чи містить поле дійсне ім'я домену (завжди проходить тест на рівні API <8)
  • ipAddress : перевіряє, чи містить поле дійсна ip-адреса
  • webUrl : перевіряє, чи містить поле дійсний URL (завжди проходить тест на рівні API <8)
  • дата : перевіряє, чи є поле дійсним форматом дати / дати (якщо встановлено customFormat, перевіряється за допомогою користувальницькоїFormat)
  • nocheck : Це не перевіряє нічого, крім порожнечі поля.

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.