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, вихідний текст замінюється на повернений.
Наприклад, якщо користувач намагається вставити літеру «а» в поле, де дозволені лише цифри, фільтр повертає «», і символ не з'являється. Якщо вставити «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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.