TextInputLayout es un componente de la biblioteca Material Components para Android que envuelve un EditText y añade capacidades avanzadas de entrada de texto. La función principal de TextInputLayout es la etiqueta flotante (floating label), que se eleva sobre el campo al introducir texto, ahorrando espacio y mejorando la legibilidad. Además, el componente admite la visualización de mensajes de error, iconos dentro del campo, un contador de caracteres y varios estilos de diseño. Según las Material Design Guidelines (2025), TextInputLayout es la forma recomendada de crear campos de texto en aplicaciones Android que cumplan con los estándares de Material Design 3.
Puntos clave
TextInputLayout es un ViewGroup del paquete com.google.android.material.textfield que extiende LinearLayout y contiene un EditText en su interior. El componente forma parte de la biblioteca Material Components para Android, desde la versión 1.0.0. El objetivo principal de TextInputLayout es proporcionar una implementación ya preparada de los campos de texto de Material Design con el mínimo esfuerzo por parte del desarrollador.
A diferencia de un EditText estándar, TextInputLayout gestiona la animación de la etiqueta flotante, que se define mediante el atributo android:hint del EditText interno. Cuando el campo está vacío, la etiqueta se muestra dentro del campo como una sugerencia normal. En cuanto el usuario empieza a escribir, la etiqueta se desplaza animadamente a la parte superior del campo, reduciendo su tamaño. Según las Material Design Guidelines (2025), esta animación mejora la percepción del formulario porque el usuario siempre ve el nombre del campo, incluso después de introducir datos.
Arquitectónicamente, TextInputLayout implementa el patrón decorador: intercepta los eventos de EditText, gestiona la visualización de elementos adicionales (etiqueta, error, iconos, contador) y coordina su animación. El EditText interno es accesible mediante el método getEditText() y puede configurarse con atributos estándar, incluyendo inputType, maxLines y 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>
La etiqueta flotante (floating label) es la característica clave de TextInputLayout. Cuando el campo está vacío, el texto de android:hint se muestra dentro del EditText como un marcador de posición normal. Cuando el campo obtiene el foco o se introduce texto, la etiqueta se eleva a la parte superior de TextInputLayout, reduciendo el tamaño de la fuente y cambiando de color. Este comportamiento resuelve el problema de que la sugerencia se vuelva invisible después de que el usuario empiece a escribir.
La configuración de la etiqueta flotante se realiza mediante los atributos de TextInputLayout: app:hintEnabled determina si la etiqueta flotante está activada (por defecto true), app:hintAnimationEnabled activa o desactiva la animación de transición, app:expandedHintEnabled permite mostrar la etiqueta incluso cuando el campo está vacío y sin foco. El color de la etiqueta en diferentes estados se gestiona mediante los estilos colorPrimary y colorControlHighlight.
Según el Google Material Components Team (2025), la etiqueta flotante es especialmente útil en formularios con muchos campos, donde el usuario podría olvidar el nombre del campo después de empezar a escribir. A diferencia de un simple android:hint que desaparece al introducir texto, la etiqueta flotante permanece visible en todo momento, proporcionando contexto para cada campo.
| Atributo | Descripción | Valor por defecto |
|---|---|---|
| hintEnabled | Activa o desactiva la etiqueta flotante | true |
| hintAnimationEnabled | Activa la animación de subida/bajada de la etiqueta | true |
| expandedHintEnabled | Muestra la etiqueta incluso si el campo está vacío y sin foco | false |
| hintTextAppearance | Estilo de texto de la etiqueta flotante | Tema de la aplicación |
TextInputLayout proporciona un sistema integrado de visualización de errores que está visualmente integrado con el campo de entrada. Al establecer un error mediante el método setError, el componente resalta el campo (el color de la línea o el contorno cambia a rojo) y muestra el texto de error debajo del campo. Esto elimina la necesidad de un TextView separado para los mensajes de error.
La gestión de la visualización de errores se realiza mediante los métodos setError(CharSequence) y setErrorEnabled(boolean). Al llamar a setError con texto, el error se muestra inmediatamente; al llamar a setError(null), se oculta. TextInputLayout también admite un icono de error personalizado mediante el atributo app:errorIconDrawable y la gestión del color de error mediante app:errorTextColor.
Según las Material Design Guidelines (2025), los mensajes de error deben ser específicos y útiles: en lugar de “Entrada no válida” escribe “El email debe contener @”. La visualización del error debe producirse después de completar la entrada (al perder el foco o después de enviar el formulario), no en tiempo real — esto reduce el estrés del usuario al rellenar formularios.
// Configuración programática de errores
textInputLayout.error = "Password min 8 chars"
// Ocultación de errores
textInputLayout.error = null
// Verificación y establecimiento de errores de validación
if (email.isNullOrBlank()) {
tilEmail.error = "Email is required"
} else {
tilEmail.error = null
}
TextInputLayout admite la visualización de iconos tanto al inicio del campo (start icon) como al final (end icon). Los iconos pueden realizar varias funciones: cambiar la visibilidad de la contraseña, borrar el campo, acciones personalizadas. Cada tipo de icono se controla mediante un atributo independiente y puede sustituirse por uno personalizado mediante los atributos app:startIconDrawable o app:endIconDrawable.
El modo de icono final se define mediante el atributo app:endIconMode, que puede tomar los siguientes valores: password_toggle — cambio de visibilidad de la contraseña, clear_text — borrado del campo, dropdown_menu — flecha para lista desplegable, custom — icono personalizado. Para password_toggle, TextInputLayout gestiona automáticamente el cambio de inputType entre textPassword y textVisiblePassword, y también anima el icono del ojo.
<!-- 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 para Android proporciona dos estilos principales para TextInputLayout: FilledBox (relleno) y OutlinedBox (con contorno). El estilo FilledBox tiene un fondo relleno de color y una línea debajo del campo que cambia de color al recibir el foco. El estilo OutlinedBox tiene un fondo transparente y un contorno alrededor de todo el campo, creando límites más claros y siendo más adecuado para formularios con muchos campos.
La elección del estilo depende del diseño de la aplicación: FilledBox se recomienda para formularios de uso frecuente, ya que atrae menos atención a los campos individuales. OutlinedBox es preferible para formularios cortos (inicio de sesión, registro) donde cada campo debe estar claramente marcado. El estilo se define mediante el atributo style en XML o a través del tema de la aplicación.
| Característica | FilledBox | OutlinedBox |
|---|---|---|
| Fondo | Relleno de color (normalmente gris) | Transparente |
| Borde | Línea inferior | Contorno alrededor del campo |
| Foco | La línea se engrosa y cambia de color | El contorno cambia de color y se engrosa |
| Recomendación | Formularios con entrada frecuente | Formularios cortos, énfasis en los campos |
| Estilo | Widget.MaterialComponents.TextInputLayout.FilledBox | Widget.MaterialComponents.TextInputLayout.OutlinedBox |
Material Design 3 (M3) introdujo estilos actualizados para TextInputLayout con tipografía mejorada, nuevos tokens de color y soporte para colores dinámicos de Material You. En M3, OutlinedBox se convirtió en el estilo recomendado por defecto, y FilledBox adaptó su relleno y radio de borde para cumplir con la nueva especificación.
Un ejemplo completo de implementación de un formulario de registro con TextInputLayout, que incluye validación de email y contraseña, visualización de errores e icono de mostrar contraseña. Al pulsar el botón de registro, se verifican todos los campos y se muestran los mensajes de error correspondientes.
@+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
}
Preguntas frecuentes
TextInputLayout está disponible a partir de la versión 1.0.0 de la biblioteca com.google.android.material. Para las funciones de Material Design 3, utiliza la versión 1.6.0 o superior. Incluye: implementation “com.google.android.material:material:1.12.0” en el build.gradle del módulo.
El color de la etiqueta flotante en estado de foco se controla mediante el atributo app:hintTextColor o a través del tema con colorPrimary. Para diferentes estados (foco, error, desactivado), utiliza un selector en res/color/ o los atributos boxStrokeColor, errorTextColor de la biblioteca Material Components.
Establece el atributo app:counterEnabled=“true” y especifica el número máximo de caracteres con app:counterMaxLength=“100”. TextInputLayout mostrará automáticamente el contador en la parte inferior del campo (por ejemplo, “25/100”). El color del contador se puede configurar mediante app:counterTextColor y app:counterOverflowTextColor para cuando se supera el límite.
FilledBox — fondo relleno de color, énfasis en la línea inferior. Ocupa menos espacio visual. OutlinedBox — fondo transparente con contorno alrededor del campo, bordes más visibles. FilledBox se recomienda para campos de uso frecuente, OutlinedBox para formularios cortos donde la claridad de cada campo es importante.
Sí, establece el atributo app:hintEnabled=“false” para desactivar la etiqueta flotante. En este caso, TextInputLayout funcionará como un envoltorio normal para EditText, conservando la funcionalidad de errores, iconos y contador de caracteres, pero sin la animación de la etiqueta. Útil para campos donde no se necesita sugerencia o se utiliza una etiqueta personalizada.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también