Reputation: 727
I have a viewmodel like this -
private val viewState = SchoolsViewState()
fun onViewOpened() =
Transformations.map(schoolUseCase.performAction(SchoolAction.GetList)) {
when (it) {
is SchoolResult.Loading -> viewState.copy(loading = true)
is SchoolResult.ListContent -> viewState.copy(loading = false, listData = it.schoolList)
is SchoolResult.Error -> viewState.copy(loading = false, error = it.error)
else -> viewState.copy(loading = false)
}
}
The viewState class looks like that -
data class SchoolsViewState(
val loading: Boolean = false,
val schoolList: List<SchoolModel> = emptyList(),
val error: SchoolResult.ErrorType? = null
)
The Fragment view model observe code looks like this -
viewModel.onViewOpened().observe(this, Observer {
//Handling the SchoolsViewState here
swipeContainer.isRefreshing = it.loading
if (it.schoolList.isNullOrEmpty()) {
view?.recycler_view?.visibility = View.GONE
view?.empty_view?.visibility = View.VISIBLE
} else {
view?.recycler_view?.visibility = View.VISIBLE
view?.empty_view?.visibility = View.GONE
view?.recycler_view?.adapter = schoolAdapter
myAdapter.setSchoolList(it.schoolList)
}
})
The problem is on every swipe refresh I see empty view first and once data is there then i see list of schools. So this is kind of a UI inconvenience. This is due to viewState.copy(...)
on every refresh gives new state to the UI. How can I overcome this problem?
Upvotes: 1
Views: 428
Reputation: 14660
You shouldn't show an empty view if your list is empty because the list is still being loaded - that doesn't make sense. Instead, you should show it only if loading = false
and your list is empty. In this case, you really don't have any other option. Hence, you code could look as follows:
viewModel.onViewOpened().observe(this, Observer {
//Handling the SchoolsViewState here
swipeContainer.isRefreshing = it.loading
// if means the loading is finished
if (!it.loading) {
if (it.schoolList.isNullOrEmpty()) {
view?.recycler_view?.visibility = View.GONE
view?.empty_view?.visibility = View.VISIBLE
} else {
view?.recycler_view?.visibility = View.VISIBLE
view?.empty_view?.visibility = View.GONE
view?.recycler_view?.adapter = schoolAdapter
myAdapter.setSchoolList(it.schoolList)
}
} else {
// here you could show some loading progress or similar
}
})
Upvotes: 2
Reputation: 11323
You are updating a different adapter's list than the one that is set as your recyler view´s adapter, see bookingsAdapter
vs myAdapter
:
view?.recycler_view?.adapter = bookingsAdapter
myAdapter.setSchoolList(it.schoolList)
That looks strange to me
Upvotes: 0