Últimos ajustes de UI en tu app Android

Resumen

Llegar al 95% de una app Android no es llegar al final. Los últimos retoques de UI y UX en Jetpack Compose definen si tu proyecto se siente profesional o queda a medias. Aquí verás cómo corregir el guardado de categorías, ajustar el teclado, mejorar el menú y construir un Empty State funcional.

¿Por qué no se guarda la categoría de una tarea en Room?

Cuando editas una tarea, cambias su categoría y al volver a abrirla aparece vacía, el problema casi siempre está en el mapeo entre el modelo de dominio y la entidad de base de datos.

En este caso, al mapear de Task a TaskEntity faltó incluir el campo category. La solución pasa por guardar el valor como un Int nulo usando el ordinal del enum, es decir, el número que Kotlin asigna automáticamente a cada entrada cuando declaras la enumeración [03:20].

¿Qué es el ordinal de un enum en Kotlin? Es el índice numérico que Kotlin asigna a cada valor del enum según el orden en que lo declaras. Empieza en 0 y sirve para persistir el valor como entero en una base de datos.

¿Cómo reconstruir el enum desde un Int con companion object?

Para recuperar la categoría desde la base de datos, necesitas una función que reciba el ordinal y devuelva la entrada correspondiente del enum. La forma idiomática en Kotlin es declarar un companion object dentro de la clase de categoría con una función fromOrdinal que recorra entries y devuelva la coincidencia.

En el código se usa con category?.let { Category.fromOrdinal(it) }, lo que mantiene la seguridad ante valores nulos.

¿Por qué hay que limpiar el caché tras cambiar el esquema?

Cualquier cambio de esquema en Room, como agregar un campo nuevo, rompe la base existente. Si no migras, debes limpiar el almacenamiento desde App Info > Storage > Clear Storage o desinstalar la app antes de volver a correrla [05:10].

¿Cómo evitar que el teclado tape el botón Save en Compose?

En dispositivos reales, el teclado virtual puede ocultar elementos críticos como el botón de guardar. La solución combina configuración del manifiesto y modifiers de Compose.

  • En el AndroidManifest.xml, añade android:windowSoftInputMode="adjustResize" a la actividad para que la ventana se redimensione cuando aparece el teclado.
  • En el composable principal de la pantalla de tarea, aplica el modificador imePadding() para que reaccione al alto del teclado.
  • Limita el crecimiento del campo de descripción cuando tiene foco, así no empuja el botón fuera de la pantalla.

¿Qué hace imePadding en Jetpack Compose? Agrega un padding inferior igual a la altura del teclado virtual cuando aparece. Así, los elementos del composable se elevan en lugar de quedar ocultos.

¿Cómo limitar las líneas de un TextField según el foco?

La idea es usar TextFieldLineLimits.MultiLine cuando el campo está enfocado, con un mínimo de una línea y un máximo de cinco. Para el resto de los casos, se usa TextFieldLineLimits.Default. Esto evita que una descripción de seis o siete líneas empuje el botón Save hacia abajo [07:40].

También se mejora el cursor con cursorBrush = SolidColor(MaterialTheme.colorScheme.secondary) para dar más contraste visual durante la edición.

¿Cómo arreglar un menú dropdown que queda superpuesto?

El botón Delete All dejaba el menú abierto encima del contenido. La corrección es directa: al seleccionar la opción, hay que cambiar el estado del menú con isMenuExpanded = false para que se cierre antes de ejecutar la acción.

Además, el mensaje de Snackbar mostraba Task updated cuando en realidad se eliminaban todas las tareas. La solución está en el HomeScreenViewModel, dentro del manejador onDeleteAllTask, donde se cambia el evento por uno que comunique All tasks deleted.

¿Por qué necesitas un Empty State en una app de tareas?

Mostrar las pestañas Pending y Complete cuando la lista está vacía rompe la coherencia visual. Un Empty State comunica al usuario que no hay nada pendiente y guía hacia la acción de crear una nueva tarea.

La implementación envuelve el LazyColumn en un else: si la lista tiene elementos, se muestra; si está vacía, aparece el componente de Empty State [11:30].

¿Cómo formatear la fecha del día de la semana en Android?

Cuando el nombre del día es largo, como Wednesday, la coma del formato genera un tick visual incómodo. Hay dos rutas: bajar el tamaño de fuente o reducir el formato a tres letras.

Dada la diversidad de densidades de pantalla en Android, lo más estable es ajustar el patrón en el HomeScreenViewModel y quitar una E del formato EEEE para dejarlo en EEE. Así obtienes Wed, Thu, Fri y el layout se mantiene limpio en cualquier dispositivo.

Con estos ajustes, la app queda al 100%. Puedes seguir sumando colores, componentes o funcionalidades nuevas. ¿Qué detalle de UX agregarías tú al proyecto? Déjalo en los comentarios.