InputFilter to interfejs Android SDK, który pozwala przechwytywać i modyfikować wprowadzany tekst przed jego wyświetleniem w EditText. Deweloper określa reguły filtracji: dozwolone znaki, maksymalną długość, format wprowadzania. Według Android Developers, 2026, InputFilter jest używany do ograniczania wprowadzania liter, cyfr, znaków specjalnych i automatycznego formatowania tekstu. W przeciwieństwie do TextWatcher, filtr działa przed zmianą tekstu, co zapobiega nieprawidłowemu wprowadzaniu na poziomie źródła.
Najważniejsze
InputFilter to funkcjonalny interfejs z pakietu android.text, który definiuje pojedynczą metodę filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend). Jest wywoływany automatycznie za każdym razem, gdy użytkownik próbuje wprowadzić, wkleić lub zastąpić tekst w EditText. Wartość zwracana określa, czy zmiana zostanie zaakceptowana, odrzucona czy zmodyfikowana.
Głównym przeznaczeniem InputFilter jest zapobieganie nieprawidłowemu wprowadzaniu zanim tekst trafi do pola. Na przykład w polu do wprowadzania cyfr numeru telefonu filtr może zabronić wprowadzania liter i znaków specjalnych. W polu hasła — ograniczyć minimalną długość. W polu kodu potwierdzenia — zezwolić tylko na cyfry. W przeciwieństwie do walidacji przez TextWatcher, filtr nie pozwala błędnym znakom nawet pojawić się na ekranie.
Według Android Developers, InputFilter jest używany we wszystkich komponentach Material Design dla TextInputEditText. Biblioteki takie jak PhoneNumberFormattingTextWatcher łączą TextWatcher i InputFilter dla pełnego formatowania. Zaleca się używanie InputFilter jako pierwszej bariery ochrony przed nieprawidłowym wprowadzaniem, a TextWatcher — do dodatkowej logiki po wprowadzeniu.
Metoda filter otrzymuje sześć parametrów: source — wprowadzany tekst, start i end — granice wprowadzanego fragmentu, dest — bieżącą zawartość pola, dstart i dend — pozycję, w której tekst jest wstawiany. Jeśli metoda zwraca null, zmiana jest akceptowana bez zmian. Jeśli zwraca pusty ciąg „“, zmiana jest blokowana. Jeśli zwraca nowy CharSequence, oryginalny tekst jest zastępowany zwróconym.
Na przykład, jeśli użytkownik próbuje wstawić literę „a“ w polu, gdzie dozwolone są tylko cyfry, filtr zwraca „“, a znak się nie pojawia. Jeśli wstawić „123“, filtr może zwrócić „1-2-3“, dodając separatory. Ten mechanizm pozwala zaimplementować automatyczne formatowanie numeru telefonu, daty i innych strukturyzowanych danych bez udziału TextWatcher.
Ważne: InputFilter nie zmienia oryginalnego źródła danych, a tylko zwraca przefiltrowaną wersję. Android sam stosuje zwróconą wartość do Editable. Jeśli filtr zwraca null, nie są wymagane żadne dodatkowe działania. Jeśli zwraca zmodyfikowany tekst, Android usuwa oryginalny zakres i wstawia nowy.
Android SDK udostępnia kilka wbudowanych implementacji InputFilter. Najpopularniejsza to InputFilter.LengthFilter, która ogranicza maksymalną długość tekstu. Konstruktor przyjmuje liczbę całkowitą — maksymalną liczbę znaków. Jeśli długość bieżącego tekstu z uwzględnieniem wprowadzania przekracza limit, filtr zwraca przycięty ciąg, nie pozwalając przekroczyć ograniczenia.
Dostępny jest również InputFilter.AllCaps, który przekształca wszystkie wprowadzane znaki na wielkie litery. Jest stosowany w polach dla kodów, kodów pocztowych i innych danych, gdzie wielkość liter ma znaczenie. Filtr nie tylko blokuje małe litery, ale je konwertuje, co jest wygodne dla użytkownika — widzi on wynik przekształcenia.
Istnieje InputFilter.LengthFilter dla wielu limitów — poprzez kombinację filtrów. Na przykład, jeśli trzeba ograniczyć długość do 20 znaków i zezwolić tylko na cyfry, można zastosować LengthFilter + niestandardowy filtr cyfrowy. Każdy filtr jest wykonywany sekwencyjnie, a wynik poprzedniego staje się dest dla następnego.
| Filtr | Przeznaczenie | Przykład użycia |
|---|---|---|
| LengthFilter | Ograniczenie długości tekstu | Pole imienia do 50 znaków |
| AllCaps | Przekształcanie na wielkie litery | Pole kodu pocztowego |
| InputFilter niestandardowy | Dowolne reguły filtracji | Tylko cyfry, znaki specjalne zabronione |
Aby utworzyć niestandardowy filtr, należy zaimplementować interfejs InputFilter i nadpisać metodę filter. Częstym zadaniem jest filtr zezwalający tylko na cyfry. W takim przypadku metoda sprawdza każdy znak z source przez Character.isDigit i zwraca przefiltrowany ciąg lub null, jeśli wszystkie znaki są dozwolone.
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
}
}
Przykład filtra DigitsInputFilter przechodzi przez wszystkie znaki wprowadzanego tekstu i pozostawia tylko cyfry. Jeśli wszystkie znaki przeszły weryfikację, metoda zwraca null — to optymalny przypadek, ponieważ nie wymaga dodatkowych operacji pamięciowych. Jeśli część znaków została odrzucona, zwracany jest nowy ciąg, a do EditText trafiają tylko cyfry.
Inny popularny scenariusz — filtr zabraniający znaków specjalnych. Implementacja jest analogiczna: sprawdzanie każdego znaku przez Character.isLetterOrDigit lub porównanie z listą dozwolonych znaków. Takie filtry są używane w polach nazwy użytkownika, wyszukiwania i innych miejscach, gdzie znaki specjalne są niedozwolone.
Filtry są ustawiane na EditText poprzez metodę setFilters(InputFilter[]). Tablica filtrów zastępuje bieżące, więc jeśli trzeba dodać filtr do istniejących, należy pobrać bieżące przez getFilters(), utworzyć nową tablicę i ustawić ją z powrotem. EditText domyślnie ma jeden filtr — LengthFilter, który jest ustawiany przez android:maxLength w XML.
val editText = findViewById<EditText>(R.id.phone_input)
editText.filters = arrayOf(
DigitsInputFilter(),
InputFilter.LengthFilter(10)
)
W przykładzie ustawiane są dwa filtry: DigitsInputFilter (tylko cyfry) i LengthFilter (maksimum 10 znaków). Kolejność filtrów w tablicy ma znaczenie: pierwszy filtr otrzymuje oryginalne wprowadzenie, przetwarza je i przekazuje wynik drugiemu. Jeśli DigitsInputFilter odfiltruje część znaków, LengthFilter zobaczy już przefiltrowany tekst i zastosuje swoje ograniczenie długości do niego.
Można również ustawiać filtry przez atrybut XML android:inputType, który automatycznie dodaje niektóre filtry. Na przykład inputType="phone" dodaje DigitsKeyListener i zezwala tylko na cyfry i niektóre znaki specjalne. Jednak dla pełnej kontroli nad filtracją zaleca się używanie setFilters programowo, szczególnie gdy trzeba łączyć kilka reguł.
InputFilter i TextWatcher pełnią różne funkcje i często są używane razem. InputFilter działa na poziomie wprowadzania — nie pozwala nieprawidłowym znakom trafić do pola. TextWatcher działa po wprowadzeniu — pozwala reagować na zmiany, wykonywać walidację złożonych reguł i aktualizować UI. Połączenie obu podejść daje najlepszy rezultat.
Na przykład dla pola wprowadzania email: InputFilter może zabronić spacji i cyrylicy na poziomie wprowadzania, a TextWatcher — sprawdzić pełne dopasowanie do wzorca email po każdej zmianie. Pierwszy chroni przed oczywistymi błędami, drugi — przed strukturalnymi. Takie rozdzielenie odpowiedzialności sprawia, że kod jest czystszy i zmniejsza obciążenie walidacji.
Według Material Design Guidelines, filtry powinny być stosowane do pól ze sztywnymi ograniczeniami: numery telefonów, kody potwierdzenia, PIN-y, kody pocztowe. Dla pól z miękką walidacją — nazwa, adres, komentarz — wystarczy TextWatcher, aby nie przeszkadzać użytkownikowi w wprowadzaniu legalnych, ale niestandardowych wartości.
| Kryterium | InputFilter | TextWatcher |
|---|---|---|
| Moment działania | Przed zmianą tekstu | Po zmianie tekstu |
| Przeznaczenie | Blokowanie nieprawidłowych znaków | Reakcja na zmiany, walidacja, UI |
| Zwracana wartość | Przefiltrowany tekst lub null | Brak (void) |
| Zastosowanie | setFilters() | addTextChangedListener() |
Często zadawane pytania
InputFilter przechwytuje wprowadzanie przed zmianą tekstu i może zablokować lub zmienić go. TextWatcher jest wywoływany po zmianie i pozwala reagować na nową wartość. InputFilter — ochrona prewencyjna, TextWatcher — przetwarzanie końcowe. Do pełnej walidacji formularza zaleca się stosowanie obu podejść.
Przekaż tablicę filtrów do metody setFilters(). Filtry są wykonywane sekwencyjnie w kolejności tablicy. Aby nie stracić istniejących filtrów, pobierz je przez getFilters(), dodaj nowe do kopii tablicy i ustaw z powrotem przez setFilters. Nie nadpisuj filtrów bez uwzględnienia już ustawionych.
Tak, InputFilter może modyfikować wprowadzanie, zwracając zmieniony CharSequence. Na przykład filtr dla numeru telefonu może dodać spacje lub nawiasy. Jednak do złożonego formatowania lepiej łączyć InputFilter z TextWatcher, ponieważ filtr jest zorientowany na blokowanie, a nie na przetwarzanie końcowe.
Dowolne: spacje, litery, cyfry, znaki specjalne, znaki Unicode. W niestandardowym filtrze określasz warunek Character.isLetter, isDigit, isWhitespace lub porównujesz z czarną/białą listą. Filtr może zezwolić tylko na łacinę, tylko cyrylicę lub tylko określony zestaw znaków.
Nie, InputFilter działa tylko przy wprowadzaniu przez użytkownika lub wklejaniu z schowka. Jeśli tekst jest ustawiany programowo przez setText(), filtry nie są stosowane. Do sprawdzenia programowego tekstu użyj walidacji przez TextWatcher lub jawnego sprawdzenia przed ustawieniem.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również