Which is the proper way to expose UI state as LiveData objects from ViewModel?


#1

Hello.

Currently, I am working on a project where ViewModel classes exposes LiveData objects for Fragments and Activities.

For a simple layout, it is easy to expose one or two LiveData objects from ViewModel to Activities.

But for a complex layout and conditions, there are some cases where my ViewModel class contains more than 10 LiveData objects for different UI state.

For example, consider following LiveData objects,

val loading: LiveData<Boolean>

val noData: LiveData<Boolean>

val users: LiveData<List<User>>

val timer: LiveData<Long>

val userSelectedImage: LiveData<String>

and so on…

So in these type of scenarios, do you recommend any proper way to provide states from ViewModel to Activities or Fragments?

It would be helpful if you can guide me in the right direction or provide me some links to read for myself.

Thank you.

Dhaval Shah


#2

IMHO, things that update in unison should be a single object emitted by a LiveData.

I don’t know enough about your app and its data to say whether any of these definitely should be combined. My guess is that loading and noData could be combined into a loadingState: LiveData<LoadingState>, where LoadingState is an enum (IN_PROGRESS, NO_DATA, COMPLETE) or possibly a sealed class (so you could have a data class Error(val cause: Throwable) as an option).

But things that update independently could (and probably should) be separate LiveData. For example, my guess is that timer is independent of the others, so having it be on its own as a LiveData<Long> seems reasonable.


#3

I have used Sealed Classes for some UI states which requires data.
But somehow I got the weird feeling that using Sealed classes for all view states is not recommended.

Can you please confirm this? Is it okay if we depend on Sealed classes for most UI states?


#4

In the end, a sealed class is just a fancy enum. I see no reason to avoid sealed classes in places where you would like an enumerated set of options, some of which might hold custom data. I know of no problems with this approach.


#5

Thank you for clearification! I will surely give Sealed classes a chance from now on.