Contenido del curso
Implementación en MVVM
- 4

Navegación y pantallas de onboarding en Compose
26:17 min - 5

Grafo de navegación en Jetpack Compose
12:05 min - 6

Creación de ViewModels para Interacción en Onboarding de Apps
15:56 min - 7

View Models en Android: Gestión de la Lógica de Negocio y UI
17:20 min - 8

Hilt y SharedPreferences en ViewModels Android
29:30 min
Pantallas de Seguimiento
Networking y Datos
Persistencia Local
Funcionalidades Avanzadas
Lanzamiento de la APP
Guardando comida en Room con MVVM
Resumen
Persistir datos en una app Android con Room y el patrón MVVM te permite construir experiencias offline, reactivas y con feedback claro para el usuario. Aquí vas a ver cómo conectar eventos, estados y una base de datos local para guardar la comida que el usuario selecciona desde una API, paso a paso dentro de un SearchViewModel.
¿Por qué usar Room con MVVM para persistir datos?
Cuando tu aplicación guarda información localmente, ganas independencia del servidor y mejoras la experiencia del usuario. Si la conexión se cae, los datos siguen ahí.
El patrón MVVM combinado con eventos y estados te da una comunicación reactiva entre la UI y los datos. Cada vez que el usuario escribe en una caja de texto o presiona un botón, disparas un evento que actualiza el estado, y la interfaz responde en tiempo real.
¿Qué ventajas tiene persistir datos con Room? Tu app funciona offline, reduce dependencia de servidores y entrega información instantánea al usuario incluso sin conexión.
¿Cómo defino los eventos en SearchEvent?
Dentro de la capa presentation, en el archivo SearchEvent, creas dos data class nuevas que representan las acciones del usuario [03:15].
OnTrackFoodClickrecibefood: TrackableFood,mealType: MealTypeydate: LocalDate. Este evento se dispara cuando el usuario confirma que quiere guardar la comida.OnAmountForFoodChangerecibefood: TrackableFoodyamount: String. Controla el cambio de estado mientras el usuario escribe la cantidad en la caja de texto.
Ambas clases heredan de SearchEvent, lo que te permite manejarlas de forma centralizada en el when del ViewModel.
¿Cómo conecto los eventos al SearchViewModel?
En el SearchViewModel agregas los nuevos branches al bloque when. Para OnAmountForFoodChange, actualizas el estado mapeando la lista trackableFood: si la comida coincide con la del evento, aplicas filterOutDigits sobre el amount para limpiar dígitos no válidos; si no coincide, retornas la misma comida [05:40].
Para OnTrackFoodClick creas una función privada llamada trackFood. Como las operaciones de Room son asíncronas y se ejecutan en funciones de suspensión, necesitas envolver la lógica en viewModelScope.launch.
Dentro de la corrutina:
- Buscas en el estado la comida que coincide con la del evento.
- Conviertes el amount a Int o haces
return@launchsi es nulo. - Llamas al use case
trackFoodUseCasepasandofood,amount,mealTypeydate. - Disparas un evento que devuelve la navegación a la home screen cuando termina el guardado.
¿Por qué Room necesita corrutinas? Porque sus operaciones son asíncronas y usan funciones suspend, evitando bloquear el hilo principal de la UI.
¿Qué hace filterOutDigits dentro del estado?
Es un use case que limpia el texto que entra a la caja: descarta caracteres no numéricos y decimales innecesarios, asegurando que el amount sea válido antes de guardarlo.
¿Cómo enlazo el SearchScreen con el ViewModel?
En la SearchScreen tenías lambdas vacías esperando los eventos. Ahora las conectas al searchViewModel.onEvent.
- En
onAmountChangeenvíasSearchEvent.OnAmountForFoodChange(food, it). - En
onTrackprimero ocultas el teclado y luego disparasSearchEvent.OnTrackFoodClickpasando food,MealType.fromString(mealName)y unLocalDate.of(año, mes, día).
También corriges el BasicTextField dentro de TrackableFoodItem: el valor estaba fijo en vacío, así que lo reemplazas por trackableFoodUiState.amount para que la caja refleje lo que el usuario escribe.
¿Cómo verifico que la base de datos se creó correctamente?
Lanzas el emulador, buscas un alimento (por ejemplo pizza), eliges una opción como Homemade Style, escribes una cantidad como 200 y presionas el check [12:50].
Desde App Inspection en Android Studio confirmas que se generó TrackerDB con la tabla TrackerFoodEntity, donde aparecen el nombre del alimento, carbohidratos, proteínas, grasas y la imagen. Las fechas (día, mes, año) se ajustarán en una clase posterior.
¿Cómo cambio el teclado a numérico en la caja de texto?
Un detalle de UX importante: cuando el usuario abre la caja para escribir cantidades, el teclado por defecto no es numérico. Vas al componente donde defines el KeyboardOptions y agregas keyboardType = KeyboardType.Number junto al ImeAction existente.
Con ese cambio mínimo, al abrir la caja aparece directamente el teclado numérico y el usuario evita saltar entre layouts de teclado.
Conceptos clave que aplicaste en esta integración
- MVVM: separa la lógica de presentación (ViewModel) de la UI (SearchScreen) y comunica ambas con eventos y estados.
- Room: framework de persistencia local de Android que requiere funciones suspend para operaciones asíncronas.
- viewModelScope.launch: corrutina ligada al ciclo de vida del ViewModel, ideal para llamadas a base de datos.
- TrackableFood y TrackableFoodUiState: modelos que viajan entre la API, el estado y la UI.
- MealType.fromString y LocalDate.of: utilidades que transforman strings y fechas al formato que espera la entidad de Room.
- App Inspection: herramienta de Android Studio para inspeccionar bases de datos en tiempo real durante el desarrollo.
¿Ya probaste guardar varios registros seguidos y revisarlos en App Inspection? Cuéntame en los comentarios qué cambios harías para manejar errores de inserción.