简体   繁体   中英

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM