Communication between Fragments using a Shared ViewModel in Android

  • The Shared ViewModel allows multiple fragments to access a single data instance linked to the activity lifecycle.
  • The use of LiveData and Transformations allows the user interface to be updated reactively and automatically in response to changes in state.
  • This architecture decouples UI components, eliminating the need for complex interfaces or direct references between fragments.

How Shared ViewModel Works

If you've ever struggled to get one part of the system to know what's happened in another, you'll know that data transfer in Android can be a real headache. When you have an application with several interdependent screens, the information synchronization It is vital so that the user does not feel that the app is broken or that the data disappears when the screen is rotated.

The most robust and modern solution we have available is the Shared ViewModelBasically, it's a data store that doesn't belong to a single fragment, but is anchored to the activity that contains them all. This way, any screen can read or write information without needing to know about the others, keeping the code clean and preventing the app from crashing due to errors. configuration changes.

What exactly is a shared ViewModel?

To put it simply, a ViewModel is a class designed to store and manage data related to the user interface. When we say it is sharedBy "scope," we mean that its scope is the host activity. As long as the activity is alive, the ViewModel will persist, meaning that if the user navigates between fragments, they will all be looking at the same "data box."

This architecture is the jewel in the crown because completely detach the fragmentsYou no longer need to create complicated interfaces or pass endless bundles as arguments. Fragment A stores data, the ViewModel retains it, and fragment B observes and reacts to it. It is, quite simply, the most efficient way to avoid memory leaks and errors of life cycle of an activity.

Step-by-step implementation and best practices

To set up this system, the first step is to create a class that inherits from ViewModelWithin it, the ideal is not to expose the variables directly. The golden rule is to use MutableLiveData privately (with an underscore, for example) _quantity) and expose a read-only version by LiveDataThis prevents any external class from modifying the data at will and causing erratic behavior.

Model-View-ViewModel
Related article:
Complete Guide to Mastering the MVVM Architectural Pattern

The secret of scope

This is where many people make mistakes. If you use delegation viewModels()Each fragment will have its own instance and there will be no communication. To share it, you must use activityViewModels() or pass the activity to the constructor of ViewModelProviderBy making the ViewModel owner Whatever the activity, you ensure that all fragments receive the same instance.

Reactive synchronization with LiveData and Data Binding

The real magic happens when we combine the ViewModel with the data bindingInstead of writing repetitive code to update each TextView, we can bind the ViewModel variable directly in the XML. For this to work, it's essential to assign the lifecycleOwner in the fragment; otherwise, the interface will not know that the data has changed and you will be left staring at a static screen.

Advanced Techniques: Transformations and Results

Sometimes we don't want to display the raw data, but a formatted version. For this, there are... LiveData TransformationsFor example, if we have a price as a decimal number, we can use Transformations.map() to automatically convert it into a text string with the local currency symbol. This allows the presentation logic reside in the ViewModel and do not clutter the fragment class.

Alternative: The Fragment Results API

We don't always need a ViewModel. If we only want to pass a single, specific piece of data (like the result of a QR code scan), the Fragment Result API It's the lightest option. This tool uses the FragmentManager like a central mailbox: one fragment establishes the result with a specific key and the receiving fragment listens to it through a listenersIt is ideal for fast, one-way communications that do not require persistence.

Real-world use cases and architecture

Imagine a cupcake order screen. In the first step, you choose the quantity, in the second the flavor, and in the third the pickup date. Thanks to the Shared ViewModel, the summary screen can access all previous decisions without the previous fragments having to send it anything explicitly. We can even calculate the total price in real time Adding surcharges if the user chooses to pick up the order on the same day.

Asynchronous and Reactive Data Flows with Kotlin Flow
Related article:
Complete Guide to Essential Kotlin Concepts for Android Development

Another typical scenario is the master-detail view on tablets. When you tap an item in a list on the left fragment, the ViewModel updates, and the right fragment, which is looking at that same data, Refresh the detailed information Instantly. All of this happens without the activity having to actively intervene in the coordination, simply functioning as the container that keeps the state alive. Share this guide and more users will be informed about the topic.


Add as preferred source