Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show LoadingState when using Room Livedata MVVM

so I'm coming from an MVP background... What I'm basically trying to do is start a loadingView as soon as we start fetching the data from Room (SQLite), stop the loadingView when successful and all of that logic should be handled in my ViewModel (trying to keep my fragment clean) class for the Fragment.

What I've done right now is that I've got two LiveData's:

  1. My actual data that comes from the DB
  2. A livedata for the state of the fragment:

Here's what I mean:

enum HomeState{
    LOADING,
    LIVE
}    
private LiveData<List<SomeData>> someData;
private MutableLiveData<HomeState> homeState;

I'm observing both in my fragment and I want to have my homeStateLiveData determine whether the fragment should be displaying a loading view.. As you can probably see, this won't work as when the new data comes it immediately goes to the fragment and I can't control the homeState logic from the ViewModel

like image 217
Martin Avatar asked Mar 07 '19 18:03

Martin


People also ask

In which method should you observe a LiveData object?

The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that the observer is notified of changes. You usually attach the Observer object in a UI controller, such as an activity or fragment.

Can we use LiveData without ViewModel?

No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data.

What is live data in MVVM?

Up until now, we've used Data Binding to update the View from the ViewModel. LiveData is a handy data holder that acts as a container over the data to be passed. The best thing about LiveData is that it is lifecycle aware. So if you are in the background, the UI won't try to update.


2 Answers

As you can probably see, this won't work as when the new data comes it immediately goes to the fragment and I can't control the homeState logic from the ViewModel

You can control the homeState based on the database LiveData by putting yourself between the fragment's observer and the database's LiveData. The way you would do this would be either through a Transformation or through a MediatorLiveData.

// with a Transformation
// this would be the method which returns the database LiveData
public LiveData<List<SomeData>> getDatabaseData() {
     // the view should show a loading indicator
     homeState.setValue(HomeState.LOADING);
     // we don't actually map anything, we just use the map function to get 
     // a callback of when the database's LiveData has finished loading  
     return Transformations.map(dao.getSomeData(), list -> {
         // the database has just finished fetching the data from the database
         // and after this method returns it will be available to the observer
         // in the fragment.
         // we also need to dismiss the loading indicator
         homeState.setValue(HomeState.LIVE);
         return list;
     });
}

With a MediatorLiveData you would do something similar, just make the MediatorLiveData listen for the database LiveData and update the homeState in the observer it sets when you add the database LiveData as its source.

If you want to abstract this, you could wrap the data you get from the database and the state(loading or available) into a single class and change your ViewModel to only return a LiveData with that class. The architecture components guide has an example(kind of related) on how you may do this, there they monitor the status of the network but you could easily adapt this to your database scenario.

like image 190
user Avatar answered Sep 30 '22 21:09

user


I am using loading state in mvvm, rx, kotlin, retorfit for recyclerview.

Here is my actual loading state.

Here is my binding adapter for observe loading state.

Here is my extended recyclerview class for loading state and empty view.

Here is my xml file for bind loading state.

Maybe you can get inspiration from my example.

like image 33
Mustafa Kuloğlu Avatar answered Sep 30 '22 20:09

Mustafa Kuloğlu