I'm exploring the Paging library of the Architecture Components suite.
My question refers to implementing the "load more" view (spinner) when using the constructs provided by Paging.
I would normally implement the endless scroll pattern manually. It means I would usually feed the adapter a list of 'viewmodels' (which aren't necessarily viewmodels in Architecture Components sense, just entities representing all the list items), including an optionally appended 'load more' object, which the adapter would then present as a 'loading' view.
This solution has certain advantages, such as better testability and keeping the UI layer as simple and passive as possible, decoupling the adapter from any business logic.
It doesn't seem that easy with Paging. From what I've seen, you're supposed to wire up a stream of PagedList instances to the PagedListAdapter.submitList method, and the magic will be happening by itself.
Then, in order to add a spinner, you'd actually expose a "network status" from the view model, pass it to the adapter separately, and have the adapter inject the spinner on the fly.
That's how it's done in the sample code - https://github.com/googlesamples/android-architecture-components/blob/master/PagingWithNetworkSample/app/src/main/java/com/android/example/paging/pagingwithnetwork/reddit/ui/PostsAdapter.kt
class PostsAdapter /* snip */ {
private var networkState: NetworkState? = null
// snip
private fun hasExtraRow() = networkState != null && networkState != NetworkState.LOADED
// snip
override fun getItemCount(): Int {
return super.getItemCount() + if (hasExtraRow()) 1 else 0
}
fun setNetworkState(newNetworkState: NetworkState?) {
val previousState = this.networkState
val hadExtraRow = hasExtraRow()
this.networkState = newNetworkState
val hasExtraRow = hasExtraRow()
if (hadExtraRow != hasExtraRow) {
if (hadExtraRow) {
notifyItemRemoved(super.getItemCount())
} else {
notifyItemInserted(super.getItemCount())
}
} else if (hasExtraRow && previousState != newNetworkState) {
notifyItemChanged(itemCount - 1)
}
}
// snip
}
I find it a bit cumbersome, bug-prone and not particularly elegant. Are there any better alternatives, or is this as good as it gets with the Paging library?