Android: Как я могу проверить ввод EditText?
Мне нужно сделать проверку ввода формы на серии EditTexts. Я использую OnFocusChangeListeners для запуска проверки после того, как пользователь вводит в каждый из них, но это не ведет себя так, как требуется для последнего EditText.
Если я нажимаю кнопку "Готово" во время ввода окончательного EditText, тогда InputMethod отключается, но технически фокус никогда не теряется на EditText (и поэтому проверка никогда не происходит).
Какое лучшее решение?
Должен ли я отслеживать, когда InputMethod отсоединяется от каждого EditText, а не когда фокус меняется? Если так, то как?
14 ответов
Почему ты не используешь TextWatcher
?
Так как у вас есть ряд EditText
ящики, подлежащие проверке, думаю, вам подойдут:
- Ваша деятельность реализует
android.text.TextWatcher
интерфейс - Вы добавляете слушателей TextChanged к вам EditText box
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
- Из переопределенных методов вы можете использовать
afterTextChanged(Editable s)
метод следующим образом
@Override
public void afterTextChanged(Editable s) {
// validation code goes here
}
Editable s
на самом деле не помогает найти, какой текст окна EditText изменяется. Но вы можете напрямую проверить содержимое полей EditText, как
String txt1String = txt1.getText().toString();
// Validate txt1String
в том же методе. Я надеюсь, что я ясно, и если я, это помогает!:)
РЕДАКТИРОВАТЬ: Для более чистого подхода обратитесь к ответу Кристофера Перри ниже.
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 */
}
});
Если вам нужны хорошие всплывающие окна и изображения для проверки при возникновении ошибки, вы можете использовать setError
метод EditText
класс, как я опишу здесь
Чтобы уменьшить детализацию логики проверки, я создал библиотеку для 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
учебный класс.
Обновленный подход - 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, зацените его, если хотите!
Это было хорошее решение отсюда
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});
Я написал класс, который расширяет EditText, который изначально поддерживает некоторые методы проверки и на самом деле очень гибок.
Текущие, как я пишу, изначально поддерживаются через методы проверки атрибутов XML:
- альфа
- буквенно-цифровой
- числовой
- универсальное регулярное выражение
- пустота строки
Вы можете проверить это здесь
Надеюсь, тебе понравится:)
Я считаю InputFilter более подходящим для проверки ввода текста на Android.
Вот простой пример: как использовать InputFilter для ограничения символов в EditText в Android?
Вы можете добавить тост, чтобы оставить отзыв о ваших ограничениях. Также проверьте тег android:inputType.
Мне нужно было выполнить проверку внутри поля, а не проверку внутри поля, чтобы проверить, что мои значения были значениями с плавающей запятой без знака в одном случае и значениями с плавающей запятой со знаком в другом. Вот что, кажется, работает для меня:
<EditText
android:id="@+id/x"
android:background="@android:drawable/editbox_background"
android:gravity="right"
android:inputType="numberSigned|numberDecimal"
/>
Обратите внимание, что у вас не должно быть пробелов внутри "numberSigned|numberDecimal". Например: "numberSigned | numberDecimal" не будет работать. Я не уверен почему.
Это выглядит действительно многообещающе и именно то, что доктор заказал для меня:
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)
- date: проверяет, является ли поле допустимым форматом даты / даты / времени (если установлен customFormat, проверяется с помощью customFormat)
- Ночек: Он не проверяет ничего, кроме пустоты поля.
В файле main.xml
Вы можете поставить следующий атрибут для проверки только буквенного алфавита, который может принять текст редактирования.
Сделай это:
android:entries="abcdefghijklmnopqrstuvwxyz"
Вы можете получить желаемое поведение, слушая, когда пользователь нажимает кнопку "Готово" на клавиатуре, а также ознакомьтесь с другими советами по работе с 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;
}});
Для проверки адреса электронной почты и пароля попробуйте
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();
}
Я создал эту библиотеку для 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