For showing/hiding progress dialogs and showing error messages from a failed network call on loading of the screen, you can use a wrapper that encapsulates the LiveData that the View is observing.
Details about this method are in the addendum to app architecture:
https://developer.android.com/jetpack/docs/guide#addendum
Define a Resource:
data class Resource<out T> constructor(
val state: ResourceState,
val data: T? = null,
val message: String? = null
)
And a ResourceState:
sealed class ResourceState {
object LOADING : ResourceState()
object SUCCESS : ResourceState()
object ERROR : ResourceState()
}
In the ViewModel, define your LiveData with the model wrapped in a Resource:
val exampleLiveData = MutableLiveData<Resource<ExampleModel>>()
Also in the ViewModel, define the method that makes the API call to load the data for the current screen:
fun loadDataForView() = compositeDisposable.add(
exampleUseCase.exampleApiCall()
.doOnSubscribe {
exampleLiveData.setLoading()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
exampleLiveData.setSuccess(it)
},
{
exampleLiveData.setError(it.message)
}
)
)
In the View, set up the Observer on creation:
viewModel.exampleLiveData.observe(this, Observer {
updateResponse(it)
})
Here is the example updateResponse()
method, showing/hiding progress, and showing an error if appropriate:
private fun updateResponse(resource: Resource<ExampleModel>?) {
resource?.let {
when (it.state) {
ResourceState.LOADING -> {
showProgress()
}
ResourceState.SUCCESS -> {
hideProgress()
// Use data to populate data on screen
// it.data will have the data of type ExampleModel
}
ResourceState.ERROR -> {
hideProgress()
// Show error message
// it.message will have the error message
}
}
}
}