Android Architecture Components: ViewModel

This is a follow up to the series on Android Architecture Components, we explored the LifeCycle and LiveData components and now we’ll get into the ViewModel components.

A ViewModel is a class that manages the retrieval and the display of data to an Activity or a Fragment, this is achieved while considering the life cycle.

Usually the data is exposed from the ViewModel in the form of LiveData that’s observed by the UI components.

A ViewModel survives configuration changes of the associated Activity/Fragment, so if an activity is destroyed due to configuration change (screen rotation for example) its ViewModel will not be re-created, instead the same instance of the ViewModel will be retained, the advantage of that is for example if the ViewModel fetches some data from a remote source before the configuration change, the data will survive the configuration change and there will be no need to re-fetch again.

Another interesting feature of ViewModel is that a ViewModel can be shared between multiple UI components, for example two fragments can share the same ViewModel, this simplifies the communication between them so instead of communication through call backs, each fragment can communicate with the ViewModel and both fragments will end with the same updated data.

Creating a ViewModel

A ViewModel is a class that extends the ViewModel class, in case the ViewModel requires a Context, it can extend the AndroidViewModel which accepts an instance of Application through its constructor.

Now let’s create a simple ViewModel that exposes a LiveData that holds a list of integers and a method that allows clients to insert new items to that list, the list is also loaded with some initial data:

And from an activity, we access the ViewModel’s data like this:

When we run that application, we’ll notice that the Logcat shows the “Loading initial data” message once, when we rotate the screen it’s not invoked again because the ViewModel is retained and the LiveData was already initialized.

Now let’s extend the above example and see how this ViewModel can be shared between two Fragments.

We will create two Fragments, MainFragment and SecondFragment.

MainFragment will display the numbers list and provide an EditText & a Button to enter new items. Also you can navigate to the SecondFragment from the MainFragment.

SecondFragment will have a similar functionality, but it will provide a button that adds a hard coded Integer value to the numbers list. In the end both fragments will look like this:

MainFragment on the left, SecondFragment on the right

Now our MainFragment code will look like this:

Pretty similar to the previous code sample, just observing the ViewModel data and adding new items on the button click.

And the SecondFragment code will be like this:

Now when run the application, we’ll notice that the same data will be displayed in both fragments, the initial data is loaded once in the MainFragment and just displayed in the SecondFragment.

If we add new items from one Fragment it will be displayed automatically when navigating to the other.

All of that because both fragments share the same ViewModel, that’s achieved by initializing the ViewModel in both fragments like this:

viewModel = ViewModelProviders.of(activity).get(DemoViewModel::class.java)

The ViewModel is provided through the Activity that holds both fragments, so it’s associated with the life cycle of the Activity, both fragments receive the same instance even if one of them replaces the other.

And that was all for the ViewModel component, Source code for the demo app available on GitHub.

Thank you.