RecyclerView remains empty with Paging Library and PositionalDataSource

From what I know, for everything to work properly the PagedList instance must be preloaded with initial data as soon as it's dispatched by the LiveData. For this to occur, the data needs to be loaded when the loadInitial() method returns, which means that you need to perform the network call synchronously and call callback.onResult() from within the loadInitial() method call before the method returns, instead of using a callback. It's safe to perform network calls synchronously there because the LivePagedListBuilder will take care of calling the PagedList.Builder() from a background thread.

Also, error handling implementation is pretty much undocumented and incomplete at this point (in version 2.1.1) so calls to the recently added callback.onError() method will fail in many cases. For example, in version 2.1.1 error handling is not implemented at all in TiledPagedList, which is the type of PagedList used for a PositionalDataSource.

Finally, if you return an exact size for the list in loadInitial() (as you do here), then in loadRange() you need to make sure that you always return exactly the number of items that is requested. If the API requests 30 items and you only return 20, your app may crash. One workaround I found out is that you can pad the results list with null values so it always has the requested size, but then you need to enable placeholders. Alternatively, don't return an exact size in loadInitial() and the list will just grow dynamically.

This API is complex and tricky to use so don't blame yourself. Google is currently working on a new version 3.0 written in Kotlin which will hopefully fix all the issues of the old one.