TextInputLayout — to komponent z biblioteki Material Components dla Android, który otacza EditText i dodaje rozszerzone możliwości wprowadzania tekstu. Główną funkcją TextInputLayout jest pływająca etykieta (floating label), która unosi się nad polem podczas wprowadzania tekstu, oszczędzając miejsce i poprawiając czytelność. Dodatkowo komponent obsługuje wyświetlanie komunikatów o błędach, ikony wewnątrz pola, licznik znaków oraz różne style wizualne. Według Material Design Guidelines (2025), TextInputLayout jest zalecanym sposobem tworzenia pól tekstowych w aplikacjach Android zgodnych ze standardami Material Design 3.
Najważniejsze
TextInputLayout — to ViewGroup z pakietu com.google.android.material.textfield, która rozszerza LinearLayout i zawiera wewnątrz EditText. Komponent wchodzi w skład biblioteki Material Components dla Android, począwszy od wersji 1.0.0. Głównym zadaniem TextInputLayout jest dostarczenie gotowej implementacji Material Design Text Fields przy minimalnym wysiłku ze strony programisty.
W przeciwieństwie do standardowego EditText, TextInputLayout zarządza animacją pływającej etykiety, która jest ustawiana przez atrybut android:hint wewnętrznego EditText. Gdy pole jest puste, etykieta wyświetla się wewnątrz pola jako zwykła podpowiedź. Gdy użytkownik zaczyna wprowadzać tekst, etykieta z animacją przesuwa się do górnej części pola, zmniejszając swój rozmiar. Według Material Design Guidelines (2025), taka animacja poprawia odbiór formularza, ponieważ użytkownik zawsze widzi nazwę pola, nawet po wprowadzeniu danych.
Architektonicznie TextInputLayout implementuje wzorzec dekoratora: przechwytuje zdarzenia EditText, zarządza wyświetlaniem dodatkowych elementów (etykieta, błąd, ikony, licznik) i koordynuje ich animację. Wewnętrzny EditText jest dostępny przez metodę getEditText() i może być skonfigurowany standardowymi atrybutami, w tym inputType, maxLines i hint.
<!-- Basic TextInputLayout markup -->
@+id/tilEmail
android:layout_width="match_parent"
android:layout_height="wrap_content">
@+id/etEmail
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
Floating label (pływająca etykieta) — to kluczowa możliwość TextInputLayout. Gdy pole jest puste, tekst z android:hint wyświetla się wewnątrz EditText jako zwykła podpowiedź. Po uzyskaniu focusa lub podczas wprowadzania tekstu etykieta unosi się do górnej części TextInputLayout, zmniejszając rozmiar czcionki i zmieniając kolor. Takie zachowanie rozwiązuje problem niewidoczności podpowiedzi po rozpoczęciu wprowadzania.
Konfiguracja floating label odbywa się przez atrybuty TextInputLayout: app:hintEnabled określa, czy pływająca etykieta jest włączona (domyślnie true), app:hintAnimationEnabled — włącza lub wyłącza animację przejścia, app:expandedHintEnabled — pozwala na wyświetlanie etykiety nawet gdy pole jest puste i nie ma focusa. Kolor etykiety w różnych stanach jest zarządzany przez style colorPrimary i colorControlHighlight.
Według Google Material Components Team (2025), floating label jest szczególnie przydatna w formularzach z dużą liczbą pól, gdzie użytkownik może zapomnieć nazwy pola po rozpoczęciu wprowadzania. W przeciwieństwie do prostego android:hint, który znika podczas wprowadzania, floating label pozostaje zawsze widoczna, zapewniając kontekst dla każdego pola.
| Atrybut | Opis | Domyślnie |
|---|---|---|
| hintEnabled | Włącza lub wyłącza pływającą etykietę | true |
| hintAnimationEnabled | Włącza animację podnoszenia/opuszczania etykiety | true |
| expandedHintEnabled | Pokazuje etykietę, nawet gdy pole jest puste i bez focusa | false |
| hintTextAppearance | Styl tekstu pływającej etykiety | Motyw aplikacji |
TextInputLayout zapewnia wbudowany system wyświetlania błędów, który jest wizualnie zintegrowany z polem wprowadzania. Po ustawieniu błędu przez metodę error, komponent podświetla pole (kolor linii lub obramowania zmienia się na czerwony) i wyświetla tekst błędu pod polem. Zastępuje to konieczność używania osobnego TextView do komunikatów o błędach.
Zarządzanie wyświetlaniem błędów odbywa się przez metody setError(CharSequence) i setErrorEnabled(boolean). Przy wywołaniu setError z tekstem błąd jest wyświetlany natychmiast; przy wywołaniu setError(null) — ukrywany. TextInputLayout obsługuje również niestandardową ikonę błędu przez atrybut app:errorIconDrawable i zarządzanie kolorem błędu przez app:errorTextColor.
Według Material Design Guidelines (2025), komunikaty o błędach powinny być konkretne i pomocne: zamiast "Nieprawidłowe dane" pisz "Email musi zawierać @". Wyświetlanie błędu powinno nastąpić po zakończeniu wprowadzania (po utracie focusa lub po wysłaniu formularza), a nie w czasie rzeczywistym — zmniejsza to stres użytkownika podczas wypełniania formularza.
// Programistyczna konfiguracja błędów
textInputLayout.error = "Password min 8 chars"
// Ukrywanie błędów
textInputLayout.error = null
// Sprawdzanie i ustawianie błędów walidacji
if (email.isNullOrBlank()) {
tilEmail.error = "Email is required"
} else {
tilEmail.error = null
}
TextInputLayout obsługuje wyświetlanie ikon zarówno na początku pola (start icon), jak i na końcu (end icon). Ikony mogą pełnić różne funkcje: zmiana widoczności hasła, czyszczenie pola, niestandardowa akcja. Każdy typ ikony jest zarządzany przez osobny atrybut i może być zastąpiony niestandardową ikoną przez atrybut app:startIconDrawable lub app:endIconDrawable.
End icon mode jest ustawiany przez atrybut app:endIconMode, który może przyjmować wartości: password_toggle — przełączanie widoczności hasła, clear_text — czyszczenie pola, dropdown_menu — strzałka dla listy rozwijanej, custom — niestandardowa ikona. Dla password_toggle TextInputLayout automatycznie zarządza przełączaniem inputType między textPassword a textVisiblePassword, a także animuje ikonę oka.
<!-- TextInputLayout with password toggle icon -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
Material Components dla Android udostępnia dwa główne style dla TextInputLayout: FilledBox (wypełniony) i OutlinedBox (z obramowaniem). Styl FilledBox ma wypełnione kolorowe tło i linię pod polem, która zmienia kolor przy focusie. Styl OutlinedBox ma przezroczyste tło i obramowanie wokół całego pola, co tworzy wyraźniejsze granice i lepiej nadaje się do formularzy z dużą liczbą pól.
Wybór stylu zależy od projektu aplikacji: FilledBox jest zalecany dla często używanych formularzy, ponieważ przyciąga mniej uwagi do poszczególnych pól. OutlinedBox jest preferowany dla krótkich formularzy (logowanie, rejestracja), gdzie każde pole powinno być wyraźnie oznaczone. Styl jest ustawiany przez atrybut style w XML lub przez motyw aplikacji.
| Cecha | FilledBox | OutlinedBox |
|---|---|---|
| Tło | Wypełnienie kolorem (zwykle szarym) | Przezroczyste |
| Granica | Linia na dole | Obramowanie wokół pola |
| Focus | Linia pogrubia się i zmienia kolor | Obramowanie zmienia kolor i pogrubia się |
| Zalecenie | Formularze z częstym wprowadzaniem | Krótkie formularze, akcent na polach |
| Styl | Widget.MaterialComponents.TextInputLayout.FilledBox | Widget.MaterialComponents.TextInputLayout.OutlinedBox |
Material Design 3 (M3) wprowadził zaktualizowane style dla TextInputLayout z ulepszoną typografią, nowymi tokenami kolorów i obsługą dynamicznych kolorów Material You. W M3 OutlinedBox stał się zalecanym domyślnym stylem, a FilledBox dostosował odstępy i promień zaokrąglenia do nowej specyfikacji.
Pełny przykład implementacji formularza rejestracji z TextInputLayout, obejmujący walidację emaila i hasła, wyświetlanie błędów oraz ikonę pokazywania hasła. Po naciśnięciu przycisku rejestracji sprawdzane są wszystkie pola i wyświetlane odpowiednie komunikaty o błędach.
@+id/tilName
app:boxBackgroundMode="outlined">
@+id/etName
android:hint="Name" />
</...TextInputLayout>
@+id/tilRegEmail
app:boxBackgroundMode="outlined">
@+id/etRegEmail
android:hint="Email"
android:inputType="textEmailAddress" />
</...TextInputLayout>
@+id/tilRegPassword
app:boxBackgroundMode="outlined"
app:endIconMode="password_toggle">
@+id/etRegPassword
android:hint="Password"
android:inputType="textPassword" />
</...TextInputLayout>
private fun validateForm(): Boolean {
var isValid = true
if (etName.text.isNullOrBlank()) {
tilName.error = "Enter your name"
isValid = false
} else {
tilName.error = null
}
val email = etRegEmail.text.toString()
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
tilRegEmail.error = "Invalid email format"
isValid = false
} else {
tilRegEmail.error = null
}
val password = etRegPassword.text.toString()
if (password.length < 8) {
tilRegPassword.error = "Password min 8 chars"
isValid = false
} else {
tilRegPassword.error = null
}
return isValid
}
Często zadawane pytania
TextInputLayout jest dostępny począwszy od wersji 1.0.0 biblioteki com.google.android.material. Dla funkcji Material Design 3 używaj wersji 1.6.0 i wyższej. Podłączenie: implementation "com.google.android.material:material:1.12.0" w build.gradle modułu.
Kolor pływającej etykiety w stanie focusa jest zarządzany przez atrybut app:hintTextColor lub przez motyw za pomocą colorPrimary. Dla różnych stanów (focus, błąd, disabled) używaj selektora w res/color/ lub atrybutów boxStrokeColor, errorTextColor z biblioteki Material Components.
Ustaw atrybut app:counterEnabled="true" i określ maksymalną liczbę znaków przez app:counterMaxLength="100". TextInputLayout automatycznie wyświetli licznik na dole pola (np. "25/100"). Kolor licznika można skonfigurować przez app:counterTextColor i app:counterOverflowTextColor dla przekroczenia limitu.
FilledBox — tło wypełnione kolorem, akcent na linii na dole. Zajmuje mniej przestrzeni wizualnej. OutlinedBox — przezroczyste tło z obramowaniem wokół pola, bardziej widoczne granice. FilledBox jest zalecany dla często używanych pól, OutlinedBox — dla krótkich formularzy, gdzie ważna jest czytelność każdego pola.
Tak, ustaw atrybut app:hintEnabled="false", aby wyłączyć pływającą etykietę. W tym przypadku TextInputLayout będzie działać jako zwykła otoczka dla EditText, zachowując funkcjonalność błędów, ikon i licznika znaków, ale bez animacji etykiety. Przydatne dla pól, gdzie hint nie jest potrzebny lub używana jest niestandardowa etykieta.
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ż