InputFilter — это интерфейс Android SDK, который позволяет перехватывать и модифицировать вводимый текст до его отображения в EditText. Разработчик задаёт правила фильтрации: разрешённые символы, максимальную длину, формат ввода. По данным Android Developers, 2026, InputFilter применяется для ограничения ввода букв, цифр, спецсимволов и автоматического форматирования текста. В отличие от TextWatcher, фильтр срабатывает до изменения текста, что предотвращает некорректный ввод на уровне источника.
Главное
InputFilter — это функциональный интерфейс из пакета android.text, который определяет единственный метод filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend). Он вызывается автоматически каждый раз, когда пользователь пытается ввести, вставить или заменить текст в EditText. Возвращаемое значение определяет, будет ли изменение принято, отклонено или модифицировано.
Основное назначение InputFilter — предотвращение некорректного ввода до того, как текст попадёт в поле. Например, в поле для ввода цифр номера телефона фильтр может запретить ввод букв и спецсимволов. В поле для пароля — ограничить минимальную длину. В поле для кода подтверждения — разрешить только цифры. В отличие от валидации через TextWatcher, фильтр не позволяет ошибочным символам даже появиться на экране.
По данным Android Developers, InputFilter используется во всех компонентах Material Design для TextInputEditText. Библиотеки вроде PhoneNumberFormattingTextWatcher комбинируют TextWatcher и InputFilter для полноценного форматирования. Рекомендуется использовать InputFilter как первый барьер защиты от некорректного ввода, а TextWatcher — для дополнительной логики после ввода.
Метод filter получает шесть параметров: source — вводимый текст, start и end — границы вводимого фрагмента, dest — текущее содержимое поля, dstart и dend — позиция, куда вставляется текст. Если метод возвращает null, изменение принимается без изменений. Если возвращает пустую строку "", изменение блокируется. Если возвращает новую CharSequence, исходный текст заменяется на возвращённый.
Например, если пользователь пытается вставить букву "a" в поле, где разрешены только цифры, фильтр возвращает "", и символ не появляется. Если вставить "123", фильтр может вернуть "1-2-3", добавляя разделители. Этот механизм позволяет реализовать автоматическое форматирование номера телефона, даты и других структурированных данных без участия TextWatcher.
Важно: InputFilter не изменяет исходный источник данных, а только возвращает отфильтрованную версию. Android сам применяет возвращённое значение к Editable. Если фильтр возвращает null, никаких дополнительных действий не требуется. Если возвращает изменённый текст, Android удаляет исходный диапазон и вставляет новый.
Android SDK предоставляет несколько встроенных реализаций InputFilter. Самая распространённая — InputFilter.LengthFilter, которая ограничивает максимальную длину текста. Конструктор принимает целое число — максимальное количество символов. Если длина текущего текста с учётом ввода превышает лимит, фильтр возвращает обрезанную строку, не позволяя превысить ограничение.
Также доступен InputFilter.AllCaps, который преобразует все вводимые символы в верхний регистр. Он применяется в полях для кодов, почтовых индексов и других данных, где регистр имеет значение. Фильтр не просто блокирует строчные буквы, а конвертирует их, что удобно для пользователя — он видит результат преобразования.
Существует InputFilter.LengthFilter для нескольких лимитов — через комбинацию фильтров. Например, если нужно ограничить длину до 20 символов и разрешить только цифры, можно применить LengthFilter + кастомный цифровой фильтр. Каждый фильтр выполняется последовательно, и результат предыдущего становится dest для следующего.
| Фильтр | Назначение | Пример использования |
|---|---|---|
| LengthFilter | Ограничение длины текста | Поле имени до 50 символов |
| AllCaps | Преобразование в верхний регистр | Поле почтового индекса |
| InputFilter кастомный | Произвольные правила фильтрации | Только цифры, спецсимволы запрещены |
Для создания кастомного фильтра нужно реализовать интерфейс InputFilter и переопределить метод filter. Частая задача — фильтр, разрешающий только цифры. В таком случае метод проверяет каждый символ из source через Character.isDigit и возвращает отфильтрованную строку или null, если все символы допустимы.
class DigitsInputFilter : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {
val sb = StringBuilder()
for (i in start until end) {
val c = source?.get(i)
if (c != null && Character.isDigit(c)) {
sb.append(c)
}
}
return if (sb.length == end - start) null else sb
}
}
Пример фильтра DigitsInputFilter проходит по всем символам вводимого текста и оставляет только цифры. Если все символы прошли проверку, метод возвращает null — это оптимальный случай, так как не требует дополнительных операций с памятью. Если часть символов отброшена, возвращается новая строка, и в EditText попадают только цифры.
Другой популярный сценарий — фильтр для запрета спецсимволов. Реализация аналогична: проверка каждого символа через Character.isLetterOrDigit или сравнение со списком разрешённых символов. Такие фильтры используются в полях имени пользователя, поисковых строках и других местах, где спецсимволы недопустимы.
Фильтры устанавливаются на EditText через метод setFilters(InputFilter[]). Массив фильтров заменяет текущие, поэтому если нужно добавить фильтр к существующим, необходимо получить текущие через getFilters(), создать новый массив и установить его обратно. У EditText по умолчанию есть один фильтр — LengthFilter, который устанавливается через android:maxLength в XML.
val editText = findViewById<EditText>(R.id.phone_input)
editText.filters = arrayOf(
DigitsInputFilter(),
InputFilter.LengthFilter(10)
)
В примере устанавливаются два фильтра: DigitsInputFilter (только цифры) и LengthFilter (максимум 10 символов). Порядок фильтров в массиве имеет значение: первый фильтр получает исходный ввод, обрабатывает его и передаёт результат второму. Если DigitsInputFilter отфильтрует часть символов, LengthFilter увидит уже отфильтрованный текст и применит своё ограничение длины к нему.
Также можно устанавливать фильтры через XML-атрибут android:inputType, который автоматически добавляет некоторые фильтры. Например, inputType="phone" добавляет DigitsKeyListener и разрешает только цифры и некоторые спецсимволы. Однако для полного контроля над фильтрацией рекомендуется использовать setFilters программно, особенно когда нужно комбинировать несколько правил.
InputFilter и TextWatcher выполняют разные функции и часто используются вместе. InputFilter работает на уровне ввода — он не позволяет некорректным символам попасть в поле. TextWatcher работает после ввода — он позволяет реагировать на изменения, выполнять валидацию сложных правил и обновлять UI. Комбинация двух подходов даёт наилучший результат.
Например, для поля ввода email: InputFilter может запретить пробелы и кириллицу на уровне ввода, а TextWatcher — проверить полное соответствие шаблону email после каждого изменения. Первый защищает от очевидных ошибок, второй — от структурных. Такое разделение ответственности делает код чище и снижает нагрузку на валидацию.
По данным Material Design Guidelines, фильтры должны применяться к полям с жёсткими ограничениями: номера телефонов, коды подтверждения, PIN-коды, почтовые индексы. Для полей с мягкой валидацией — имя, адрес, комментарий — достаточно TextWatcher, чтобы не мешать пользователю вводить легитимные, но нестандартные значения.
| Критерий | InputFilter | TextWatcher |
|---|---|---|
| Момент срабатывания | До изменения текста | После изменения текста |
| Назначение | Блокировка некорректных символов | Реакция на изменения, валидация, UI |
| Возвращаемое значение | Отфильтрованный текст или null | Нет (void) |
| Применение | setFilters() | addTextChangedListener() |
Часто задаваемые вопросы
InputFilter перехватывает ввод до изменения текста и может заблокировать или изменить его. TextWatcher вызывается после изменения и позволяет реагировать на новое значение. InputFilter — превентивная защита, TextWatcher — пост-обработка. Для полной валидации формы рекомендуется использовать оба подхода.
Передайте массив фильтров в метод setFilters(). Фильтры выполняются последовательно в порядке массива. Чтобы не потерять существующие фильтры, получите их через getFilters(), добавьте новые в копию массива и установите обратно через setFilters. Не перезаписывайте фильтры без учёта уже установленных.
Да, InputFilter может модифицировать ввод, возвращая изменённую CharSequence. Например, фильтр для номера телефона может добавить пробелы или скобки. Однако для сложного форматирования лучше комбинировать InputFilter с TextWatcher, так как фильтр ориентирован на блокировку, а не на пост-обработку.
Любые: пробелы, буквы, цифры, спецсимволы, символы Unicode. В кастомном фильтре вы определяете условие Character.isLetter, isDigit, isWhitespace или сравниваете с чёрным/белым списком. Фильтр может разрешить только латиницу, только кириллицу или только определённый набор символов.
Нет, InputFilter срабатывает только при вводе пользователем или при вставке из буфера обмена. Если текст устанавливается программно через setText(), фильтры не применяются. Для проверки программного текста используйте валидацию через TextWatcher или явную проверку перед установкой.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также