Comunicación entre Fragments usando un Shared ViewModel en Android

  • El Shared ViewModel permite que mĆŗltiples fragmentos accedan a una Ćŗnica instancia de datos vinculada al ciclo de vida de la actividad.
  • El uso de LiveData y Transformaciones permite actualizar la interfaz de usuario de forma reactiva y automĆ”tica ante cambios en el estado.
  • Esta arquitectura desacopla los componentes de la IU, eliminando la necesidad de interfaces complejas o referencias directas entre fragmentos.

cómo funciona Shared ViewModel

Si alguna vez te has peleado intentando que un fragmento sepa lo que ha pasado en otro, sabrÔs que pasar datos en Android puede llegar a ser un auténtico quebradero de cabeza. Cuando tenemos una aplicación con varias pantallas que dependen entre sí, la sincronización de la información es vital para que el usuario no sienta que la app estÔ rota o que los datos desaparecen al girar la pantalla.

La solución mÔs robusta y moderna que tenemos a mano es el Shared ViewModel. BÔsicamente, se trata de un almacén de datos que no pertenece a un solo fragmento, sino que estÔ anclado a la actividad que los contiene a todos. De esta forma, cualquier pantalla puede leer o escribir información sin tener que conocer la existencia de las demÔs, manteniendo el código limpio y evitando que la app explote por culpa de los cambios de configuración.

¿Qué es exactamente un ViewModel compartido?

Para entenderlo fÔcil, un ViewModel es una clase diseñada para almacenar y gestionar datos relacionados con la interfaz de usuario. Cuando decimos que es compartido, nos referimos a que su alcance (scope) es la actividad anfitriona. Mientras la actividad esté viva, el ViewModel persistirÔ, lo que significa que si el usuario navega entre fragmentos, todos estarÔn mirando la misma «caja de datos».

Esta arquitectura es la joya de la corona porque desacopla totalmente los fragmentos. Ya no necesitas crear interfaces complicadas ni pasar bundles infinitos a travƩs de argumentos. El fragmento A guarda un dato, el ViewModel lo retiene y el fragmento B lo observa y reacciona. Es, sencillamente, la manera mƔs eficiente de evitar fugas de memoria y errores del ciclo de vida de una activity.

Implementación paso a paso y buenas prÔcticas

Para montar este sistema, lo primero es crear una clase que herede de ViewModel. Dentro de ella, lo ideal es no exponer las variables directamente. La norma de oro es usar MutableLiveData de forma privada (con un guion bajo, por ejemplo _quantity) y exponer una versión de solo lectura mediante LiveData. Así evitamos que cualquier clase externa modifique los datos a su antojo y cause comportamientos errÔticos.

Modelo-Vista-ViewModel
ArtĆ­culo relacionado:
Guía Completa para Dominar el Patrón Arquitectónico MVVM

El secreto del alcance (Scope)

Aquí es donde mucha gente mete la pata. Si usas la delegación viewModels(), cada fragmento tendrÔ su propia instancia y no habrÔ comunicación alguna. Para que sea compartido, debes emplear activityViewModels() o pasar la actividad al constructor de ViewModelProvider. Al hacer que el dueño del ViewModel sea la actividad, garantizas que todos los fragmentos reciban la misma instancia.

Sincronización reactiva con LiveData y Data Binding

La verdadera magia ocurre cuando combinamos el ViewModel con el Data Binding. En lugar de escribir código repetitivo para actualizar cada TextView, podemos vincular la variable del ViewModel directamente en el XML. Para que esto funcione, es fundamental asignar el lifecycleOwner en el fragmento; de lo contrario, la interfaz no se enterarÔ de que los datos han cambiado y te quedarÔs mirando una pantalla estÔtica.

TƩcnicas avanzadas: Transformaciones y Resultados

A veces no queremos mostrar el dato bruto, sino una versión formateada. Para ello existen las Transformaciones de LiveData. Por ejemplo, si tenemos un precio como número decimal, podemos usar Transformations.map() para convertirlo automÔticamente en una cadena de texto con el símbolo de moneda local. Esto permite que la lógica de presentación resida en el ViewModel y no ensucie la clase del fragmento.

Alternativa: La API de Fragment Results

No siempre necesitamos un ViewModel. Si solo queremos pasar un dato puntual y único (como el resultado de un escaneo de código QR), la API de Fragment Result es la opción mÔs ligera. Esta herramienta utiliza el FragmentManager como un buzón central: un fragmento establece el resultado con una clave específica y el fragmento receptor lo escucha mediante un listener. Es ideal para comunicaciones unidireccionales y rÔpidas que no requieren persistencia.

Casos de uso reales y arquitectura

Imagina una pantalla de pedidos de magdalenas. En la primera fase eliges la cantidad, en la segunda el sabor y en la tercera la fecha de recogida. Gracias al Shared ViewModel, la pantalla de resumen puede acceder a todas las decisiones previas sin que los fragmentos anteriores tengan que enviarle nada explĆ­citamente. Incluso podemos calcular el precio total en tiempo real sumando recargos si el usuario elige recoger el pedido el mismo dĆ­a.

Flujos de Datos AsĆ­ncronos y Reactivos con Kotlin Flow
ArtĆ­culo relacionado:
GuĆ­a Completa de Conceptos Esenciales de Kotlin para el Desarrollo en Android

Otro escenario típico es la vista de maestro-detalle en tablets. Al tocar un elemento de una lista en el fragmento izquierdo, el ViewModel se actualiza y el fragmento derecho, que estÔ observando ese mismo dato, refresca la información detallada al instante. Todo esto ocurre sin que la actividad tenga que intervenir activamente en la coordinación, funcionando simplemente como el contenedor que mantiene vivo el estado. Comparte esta guía y mÔs usuarios estarÔn informados del tema.


Add as preferred source