Android: Как я могу проверить ввод EditText?
Мне нужно сделать проверку ввода формы в серии EditTexts. Я использую OnFocusChangeListeners для запуска проверки после того, как пользователь вводит в каждый из них, но это не ведет себя так, как требуется для последнего EditText.
Если я нажимаю кнопку "Готово" при вводе в окончательный EditText, то InputMethod отключается, но технически фокус никогда не теряется на EditText (и поэтому проверка не происходит).
Какое лучшее решение?
Должен ли я отслеживать, когда InputMethod отключается от каждого EditText, а не при изменении фокуса? Если да, то как?
Ответы
Ответ 1
Почему вы не используете TextWatcher
?
Поскольку у вас есть количество ящиков EditText
для проверки, я думаю, вам понравится следующее:
- Ваша деятельность реализует интерфейс
android.text.TextWatcher
- Вы добавляете слушателей TextChanged к вам. Окна EditText.
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
в том же методе. Надеюсь, я поняла, и если да, то это помогает!:)
EDIT: Для более чистого подхода см. ответ Кристофера Перри ниже.
Ответ 2
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 */
}
});
Ответ 3
Если вы хотите получить хорошие всплывающие окна и изображения при возникновении ошибки, вы можете использовать метод setError
класса EditText
, как я описываю здесь
![Screenshot of the use of setError taken from Donn Felker, the author of the linked post]()
Ответ 4
Чтобы уменьшить многословие логики проверки, я создал библиотеку для 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
.
Ответ 5
Это было приятное решение от здесь
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});
Ответ 6
Я считаю InputFilter более подходящим для проверки ввода текста на Android.
Вот простой пример:
Как использовать InputFilter для ограничения символов в EditText на Android?
Вы можете добавить Toast для обратной связи с пользователем о ваших ограничениях.
Также проверьте, нет ли андроида: inputType.
Ответ 7
Я написал класс, который расширяет EditText, который поддерживает изначально некоторые методы проверки и на самом деле очень гибкий.
Текущий, как я пишу, изначально, поддерживаемый с помощью xml-атрибутов:
- альфа
- alpha numeric
- Числовое
- общее регулярное выражение
- пустота строки
Вы можете проверить это здесь
Надеюсь, вам понравится:)
Ответ 8
Обновленный подход - 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, проверьте пример, если хотите!
Ответ 9
Мне нужно было провести проверку внутри поля, а не проверку между полями, чтобы проверить, что мои значения были беззнаковыми значениями с плавающей запятой в одном случае и знаками с плавающей запятой в другой. Вот что мне кажется:
<EditText
android:id="@+id/x"
android:background="@android:drawable/editbox_background"
android:gravity="right"
android:inputType="numberSigned|numberDecimal"
/>
Обратите внимание: у вас не должно быть пробелов внутри "numberSigned | numberDecimal". Например: "numberSigned | numberDecimal" не будет работать. Я не знаю, почему.
Ответ 10
Это выглядит действительно многообещающим, и именно то, что заказал мне документ:
Валидатор 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: для пользовательского регулярного выражения
- число: только для числового поля
- alpha: для поля только альфа
- alphaNumeric: угадайте, что?
- personName: проверяет, является ли введенный текст персоной первой или последней фамилии.
- personFullName: проверяет, является ли введенное значение полным полным именем.
- электронная почта: проверяет правильность поля в поле
- creditCard: проверяет, что поле содержит действительную кредитную карту, используя алгоритм Луна
- телефон: проверяет, что поле содержит действительный номер телефона
- domainName: проверяет, что это поле содержит допустимое имя домена (всегда проходит тест на уровне API < 8)
- ipAddress: проверяет, что поле содержит допустимый IP-адрес
- webUrl: проверяет, что поле содержит действительный url (всегда проходит тест на уровне API < 8)
- date: проверяет, что поле является допустимым форматом date/datetime (если установлен customFormat, проверяется с помощью customFormat)
- nocheck: он не проверяет ничего, кроме пустоты поля.
Ответ 11
Вы можете получить желаемое поведение, слушая, когда пользователь нажимает кнопку "Готово" на клавиатуре, а также выдает другие советы о работе с 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;
}});
Ответ 12
В файле main.xml
Вы можете поместить следующий attrubute для проверки только символа алфавита, который может принимать в edittext.
Сделайте это:
android:entries="abcdefghijklmnopqrstuvwxyz"
Ответ 13
для проверки подлинности электронной почты и пароля
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();
}
Ответ 14
Я создал эту библиотеку для 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