Вы не должны делать состояние загрузки «двойным» (true / false).Ваше состояние прогресса должно отправляться только при загрузке, тогда вы переходите в состояние успеха или сбоя.Никогда не возвращайтесь в состояние загрузки в конце.При этом вы всегда знаете, в каком состоянии должен отображаться ваш вид.
- при загрузке -> показать загрузчик
- в случае успеха -> скрыть загрузчик, показать данные
- еслиошибка -> скрыть загрузчик, показать ошибку
Вот пример извлечения из моего шаблона Android Conductor + MVVM + Dagger , он использует проводник, но вы можете заменить контроллер проводника фрагментомили деятельность, это та же логика.
sealed class DataRequestState<T> {
class Start<T> : DataRequestState<T>()
class Success<T>(var data: T) : DataRequestState<T>()
class Error<T>(val error: Throwable) : DataRequestState<T>()
}
ViewModel:
@ControllerScope
class HomeControllerViewModel
@Inject
constructor(homeRepositoryManager: HomeRepositoryManager) : BaseControllerViewModel(),
DataFetchViewModel<Home> {
private val _dataFetchObservable: DataRequestLiveData<Home> =
DataRequestLiveData(homeRepositoryManager.home())
override val dataFetchObservable: LiveData<DataRequestState<Home>> = _dataFetchObservable
override fun refreshData() {
_dataFetchObservable.refresh()
}
}
Базовый контроллер данных (фрагмент / деятельность / проводник):
abstract class BaseDataFetchController<VM, D> :
BaseViewModelController<VM>() where VM : BaseControllerViewModel, VM : DataFetchViewModel<D> {
override fun onViewCreated(view: View) {
super.onViewCreated(view)
viewModel.dataFetchObservable.observe(this, Observer {
it?.let {
when (it) {
is DataRequestState.Start -> dataFetchStart()
is DataRequestState.Success -> {
dataFetchSuccess(it.data)
dataFetchTerminate()
}
is DataRequestState.Error -> {
dataFetchError(it.error)
dataFetchTerminate()
}
}
}
})
}
protected abstract fun dataFetchStart()
protected abstract fun dataFetchSuccess(data: D)
protected abstract fun dataFetchError(throwable: Throwable)
}