Error State es un estado de campo de entrada que señala visualmente datos no válidos. En Android, Error State se implementa mediante TextInputLayout.setError(), que resalta el borde en rojo y muestra el texto de error debajo del campo. Según Material Design Guidelines, 2026, Error State debe ser notable pero no agresivo: borde rojo, texto de error, icono. El uso adecuado de Error State aumenta la conversión de formularios en un 20-30%, ya que los usuarios detectan y corrigen errores rápidamente sin perder contexto.
Puntos clave
Error State es un modo de visualización especial de un campo de entrada que se activa cuando los datos introducidos no pasan la validación. Visualmente, Error State incluye tres componentes: un cambio en el color del borde o fondo del campo (generalmente a rojo), la aparición de un mensaje de texto debajo del campo describiendo el error y, opcionalmente, un icono o resaltado. El propósito de Error State es atraer instantáneamente la atención del usuario hacia el campo problemático y sugerir cómo corregir el error.
En Android, Error State se implementa a nivel de TextInputLayout de Material Design Components. TextInputLayout envuelve EditText y gestiona sus estados: normal, focused, error, disabled. El método setError(String) cambia el campo al estado de error, modifica el color del borde y muestra el mensaje. Cuando el texto cambia o se llama a setError(null), el campo vuelve a normal.
Según Material Design Guidelines, Error State debe ser notable pero no dominante. El color rojo del borde debe contrastar con el estado normal pero sin sobrecargar la interfaz. El mensaje de error debe contener información específica sobre el problema y cómo solucionarlo. Un icono de error (por ejemplo, un círculo rojo con un signo de exclamación) refuerza la señal visual.
El método setError(CharSequence errorText) cambia TextInputLayout al estado de error. El parámetro errorText es el texto que se muestra debajo del campo. Si se pasa null, el error se limpia. TextInputLayout gestiona la animación: el texto de error aparece con una suave transición de opacidad, el borde cambia a rojo. Un icono de error (por defecto: signo de exclamación en un círculo) se muestra al final del campo.
Detalles importantes: setErrorEnabled(true) debe llamarse antes de setError para reservar espacio para el mensaje de error. De lo contrario, el diseño puede "saltar" cuando aparece el error porque el espacio no está reservado. Se recomienda habilitar siempre la compatibilidad con errores en XML mediante app:errorEnabled="true" para evitar desplazamientos del diseño.
El método setError se limpia automáticamente cuando el texto del campo cambia si setErrorEnabled(true) está habilitado. Este comportamiento es conveniente para la validación en tiempo real: tan pronto como el usuario comienza a corregir el error, el borde rojo desaparece y el campo vuelve a la normalidad. Sin embargo, para escenarios complejos, este auto-limpieza puede ser indeseable; en tales casos, gestione el error manualmente.
val til = findViewById<TextInputLayout>(R.id.til_email)
// Habilitar soporte de error (configurar en XML si no)
til.isErrorEnabled = true
// Establecer mensaje de error
til.error = "Invalid email address"
// Limpiar error
til.error = null
// Verificar si existe error
if (til.error != null) {
// El campo está en estado de error
}
El ejemplo utiliza propiedades de Kotlin para acceder a setError/isErrorEnabled. TextInputLayout actualiza automáticamente la interfaz de usuario: cambia boxStrokeColor, muestra el icono de error, muestra el texto de error. Si el texto en EditText cambia, el error se limpia automáticamente. Para restablecer manualmente, asigne error = null.
No todos los proyectos utilizan Material Design Components. Para visualización personalizada de errores, puede usar un TextView separado debajo del EditText que se vuelve visible al ocurrir un error. Este enfoque ofrece control total sobre los estilos y la ubicación del mensaje. Por ejemplo, puede colocar el mensaje a la derecha del campo, usar un color de fondo diferente o agregar un icono a la izquierda del texto.
En Jetpack Compose, Error State se implementa mediante el parámetro isError en OutlinedTextField o TextField. Cuando isError = true, el borde se vuelve rojo y puede mostrar el texto de error a través de supportingText. Compose no tiene auto-limpieza incorporado al cambiar el texto — el desarrollador gestiona el estado de error manualmente usando remember y mutableStateOf.
Para errores de grupo (un solo mensaje para varios campos, por ejemplo, "Complete todos los campos obligatorios"), use Snackbar, Dialog o un bloque en línea en la parte superior del formulario. Un error de grupo no reemplaza el Error State de campos individuales sino que lo complementa. El usuario primero ve el mensaje general, luego busca campos específicos con errores.
| Método | Ventajas | Desventajas | Cuándo usarlo |
|---|---|---|---|
| TextInputLayout.setError | Estándar, animación, auto-limpieza | Solo con Material Components | Opción principal para MDC |
| TextView separado | Control total de estilos | Gestión manual de visibilidad | Temas personalizados, sin MDC |
| Compose isError | Integrado en Compose | Gestión manual del estado | Proyectos en Jetpack Compose |
| Snackbar/Dialog | Mensaje grupal | No vinculado a un campo específico | Complemento al Error State del campo |
El color de Error State en Material Design Components se controla mediante el atributo boxStrokeErrorColor o el atributo colorError en el tema. Por defecto se usa el color rojo del sistema, pero se puede sobrescribir en el tema de la aplicación o directamente en TextInputLayout mediante app:boxStrokeErrorColor="@color/customErrorColor". Para soporte de tema oscuro, se recomienda usar un selector con diferentes colores para modos claro y oscuro.
Icono de error se configura mediante app:errorIconDrawable. Por defecto se muestra un signo de exclamación en un círculo. Se puede reemplazar con un icono personalizado o eliminarlo por completo estableciendo app:errorIconDrawable="@null". El icono se muestra al final de TextInputLayout y sirve como marcador visual adicional. En Material Design 3, el icono de error es obligatorio para accesibilidad.
Animación de aparición del error está integrada en TextInputLayout: el texto aparece deslizándose desde abajo con un cambio suave de opacidad. Para animación personalizada, use Transition API o MotionLayout. Por ejemplo, agitar el campo al ocurrir un error atrae atención adicional. Sin embargo, el uso excesivo de animaciones empeora la UX — la aparición suave del mensaje es suficiente.
La gestión de Error State se divide en dos etapas: establecer el error durante la validación del campo y limpiar el error al corregirlo. En el caso más simple, la validación se llama en TextWatcher.afterTextChanged: si el valor no es válido, se llama a setError con un mensaje de error. Si es válido, se llama a setError(null). TextInputLayout oculta automáticamente el error cuando setError(null) limpia el estado.
Para validación de formularios, los errores se establecen en la etapa de envío del formulario. Recorra todos los campos, valide cada uno, establezca errores para campos no válidos y enfoque el primer campo con error. El botón de envío se bloquea durante este proceso. Si el formulario es grande, se recomienda desplazarse al primer campo con error y establecer el foco automáticamente.
La regla de foco único de error: al enviar un formulario, establezca el foco solo en el primer campo con error. El usuario corrige un error a la vez, y después de la corrección, el siguiente campo con error recibe el foco automáticamente. Este enfoque paso a paso reduce la carga cognitiva. Material TextInputLayout no intercepta el foco al establecer un error — esto debe hacerse manualmente mediante requestFocus().
El primer error — falta de isErrorEnabled. Si setErrorEnabled no se llama antes de setError, el diseño puede desplazarse cuando aparece el mensaje de error. Esto es especialmente crítico si el campo está en medio de la pantalla — el usuario pierde su posición de desplazamiento. Siempre habilite setErrorEnabled(true) en XML mediante app:errorEnabled="true" o programáticamente antes de establecer un error.
El segundo error — mensaje de error demasiado largo. El texto largo se divide en varias líneas y puede superponerse a los campos vecinos. La longitud recomendada del mensaje de error es de 20 a 40 caracteres. Si se necesita más información, use helperText en el estado normal o un tooltip para explicación adicional. La brevedad es la base de un buen Error State.
El tercer error — ignorar la accesibilidad. Error State debe ser accesible para lectores de pantalla. TextInputLayout anuncia automáticamente el error mediante contentDescription, pero las implementaciones personalizadas deben hacerlo manualmente. Use announceForAccessibility() o android:importantForAccessibility para mensajes de error. Los usuarios de TalkBack deben escuchar el error inmediatamente después de que aparezca.
| Error | Problema | Solución |
|---|---|---|
| Sin isErrorEnabled | Desplazamiento del diseño al mostrar error | app:errorEnabled="true" en XML |
| Mensaje largo | Superposición de campos vecinos | 20-40 caracteres, helperText para detalles |
| Sin accesibilidad | El lector de pantalla no escucha el error | Importante para usuarios de TalkBack |
| Auto-limpieza sin verificación | El campo se considera válido incorrectamente | Gestión manual del restablecimiento de error |
Preguntas frecuentes
Si usa TextInputLayout, llame a setError(null). Habilite setErrorEnabled(true) para que el espacio debajo del mensaje permanezca reservado, pero el texto desaparezca. Cuando el texto en EditText cambia, TextInputLayout limpia automáticamente el error. Para control manual, use addTextChangedListener y setError(null) en cada cambio.
Porque el espacio para el mensaje de error no está reservado. Solución: habilite app:errorEnabled="true" en XML para TextInputLayout. Esto reserva espacio para el mensaje y el diseño no se desplazará. Cuando el error está inactivo, el espacio permanece vacío pero el diseño es estable.
Use el atributo app:boxStrokeErrorColor en XML o programáticamente mediante til.setBoxStrokeErrorStateList(). El color se puede establecer con un selector para diferentes estados. También puede sobrescribir el atributo de sistema colorError en el tema de la aplicación para cambiar el color de error globalmente para todos los campos.
Sí, use app:errorEnabled="true" y setError() — pero sobrescriba boxStrokeErrorColor al color predeterminado del campo. El icono y el texto de error seguirán siendo visibles, pero el borde permanecerá del color original. Sin embargo, esto reduce la visibilidad del error, lo que contradice las recomendaciones de accesibilidad de Material Design.
En Compose, use isError = true en OutlinedTextField o TextField. El texto de error se pasa mediante el parámetro supportingText. Gestione el estado con mutableStateOf. Limpie isError manualmente cuando el texto cambie. Compose no tiene auto-limpieza de errores, a diferencia de TextInputLayout en el sistema View.
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