Не так давно мне понадобилось добавить в андроид-приложение валидаторы для полей ввода (EditText), но ничего подходящего в сети не нашлось: пришлось писать свои собственные. Теперь, когда все готово, можно раздать результаты всем желающим под Apache лицензией и немного рассказать, как все устроено. Тех, кому интересно, прошу под кат.
Так как писалось все с нуля, то можно было делать архитектуру под себя, поэтому была выбрана следующая схема:
- Одному полю ввода назначается один валидатор (можно больше, но в этом нет смысла)
- Каждому валидатору назначается несколько чекеров, на различные условия (длину текста, соответствие маске и т.п.)
- Чекеры выполняют проверки в том порядке, в котором были добавлены, первый «провалившийся» показывает сообщение.
Для удобства сделал пару кастомизаций:
- Можно выбрать проверку как по изменению текста в поле, так и вручную
- Можно показывать сообщение как в отдельном TextView, так и встроенным в андроид механизмом (красная иконка со всплывающим сообщением).
- Можно объединить валидаторы в группу и инициировать проверку для всей группы, а также показать отдельное сообщение, если хоть один валидатор в группе обнаружил ошибку.
У валидаторов и чекеров есть базовые абстрактные классы, реализовав которые, вы можете получить валидаторы для своих контролов и свои особые проверки.
Сейчас есть проверки:
- На пустоту строки
- На длину строки
- На соответствие регэкспу
- На принадлежность диапазону (для полей ввода целочисленных значений)
- На совпадение с текстом в другом поле ввода (полезно для подтверждения паролей)
В коде все это выглядит примерно так:
//Создали группирующий валидатор
ValidationSummary summaryValidator_ = new ValidationSummary(getString(R.string.common_error_message), headerErrorMessage);
//Создали валидатор для поля ввода имени
EditTextValidator firstnameValidator = new EditTextValidator();
//Назначили ему EditText для валидации, выбрав ручной режим проверки (не будет валидации, когда пользователь начнет вводить текст)
firstnameValidator.setViewToValidate(firstnameEdit, ValidationMode.Manual);
//Установили TextView для отображения сообщений об ошибках в нем, а не в штатном всплывающем окне
firstnameValidator.setExternalErrorView( (TextView) findViewById(R.id.firstname_error_text));
//Добавили проверки на пустоту строки
firstnameValidator.addConditionChecker(new NotEmptyChecker( getString(R.string.name_required_error_message) ));
//и ее длину
firstnameValidator.addConditionChecker(new LengthChecker(1, 50, getString(R.string.firstname_error_message) ));
//Добавили валидатор в группу
summaryValidator_.addValidator(firstnameValidator);
...
//Аналогично для поля подтверждения пароля
EditTextValidator confirmPasswordValidator = new EditTextValidator();
confirmPasswordValidator.setViewToValidate(confirmPasswordEdit, ValidationMode.Manual);
confirmPasswordValidator.setExternalErrorView( (TextView) findViewById(R.id.confirm_password_error_text));
//Только проверка на соответствие текста, содержимому другого поля - passwordEdit
confirmPasswordValidator.addConditionChecker(new TextMatchChecker(getString(R.string.confirm_password_error_message), passwordEdit));
summaryValidator_.addValidator(confirmPasswordValidator);
Инициировать проверку всех валидаторов в группе можно вызовом:
summaryValidator_.performCheck();
Всех, кого заинтересовали валидаторы, приглашаю взять проект с ГитХаба компании Rus Wizards, в стенах которой и был написан этот код.
И, конечно же, любые пожелания, предложение, советы приветствуются!