Android Architecture: Communication between ViewModel and View

ViewModel and View communication (source)

Introduction

Problem

Presenters and ViewModels shouldn’t hold references to Views.

In case of Presenter we usually define some sort of Contract interface where View implements Contract.view and Presenter implements Contract.presenter. And now Presenter can easily call methods on View.

EditProfileContract.Kt

ViewModel on the other hand is more loosely coupled with the View. We usually expose data using LiveData or RxJava. Once View is subscribed to the ViewModel, it starts to receive updates. This approach works pretty well when passing data to Views but problem arises when ViewModel needs to communicate View state, progress indicator status, validation/server errors.

Solution

  • Data → This is something that needs to be presented on the View like user object for user profile or feed items for social feed. Most code samples show how to pass data from ViewModel to View so I’ll leave it out for brevity sake.
  • Status → This could be anything which needs to be passed only once like validation errors, no network error, server errors.
Status.Kt

Live data doesn’t provide any out of the box solution but there’s an implementation of it called SingleLiveEvent provided in Google samples which works pretty well in here. Create a SingleLiveEvent which expose status LiveData to View layer.

EditProfileViewModel.Kt

View just observe status LiveData and performs action based on different status/errors. In this example we can easily show different toast/snackbar for each error.

EditProfileFragment.Kt
  • State → UI state like progress indicator, dialogs, which should be passed to the View every time it starts observing ViewModel data. Simply we can create a data class to hold the state.
EditProfileState.Kt

Create state as MutableLiveData in ViewModel. And since we only expose LiveData to View layer, we should also provide setters for View to update it’s state.

EditProfileViewModel.Kt

Show or hide City/Gender dialog in View layer based on the state data.

EditProfileFragment.Kt

Summary

If you have any suggestions I’d love to hear them. Happy coding!

Android Architect + UI/UX Enthusiast = Product Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store