因此,我使用了 JetPack 工具中 Android 的新分页库部分。
我正在做一个非常基本的演示应用程序,其中显示了我从RandomUser API 获得的随机用户配置文件列表。
问题是我已经设置好了所有东西,它实际上有点工作。
在我的列表片段中,我正在监听数据库更改:
...
mainViewModel.userProfiles.observe(this, Observer { flowableList ->
usersAdapter.submitList(flowableList) })
...
(我尝试了两者,使用Flowables
和Observables
,RxPagedListBuilder
现在我正在使用LiveData
。如果可能LivePagedListBuilder
的话,我想使用)RxPagedListBuilder
在我的 ViewModel 中,我正在设置LivePagedListBuilder
...
private val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(UserProfileDataSource.PAGE_SIZE / 2) //Is very important that the page size is the same everywhere!
.setPageSize(UserProfileDataSource.PAGE_SIZE)
.build()
val userProfiles: LiveData<PagedList<UserProfile>> = LivePagedListBuilder(
UserProfileDataSourceFactory(userProfileDao), config)
.setBoundaryCallback(UserProfileBoundaryCallback(randomUserRepository, userProfileDao))
.build()
...
我已将 DataSource 设置为从我的数据库中获取数据(如果有的话):
class UserProfileDataSource(val userDao: UserDao): PageKeyedDataSource<Int, UserProfile>() {
companion object {
const val PAGE_SIZE = 10
}
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, UserProfile>) {
callback.onResult(userDao.getUserProfileWithLimitAndOffset(PAGE_SIZE, 0), 0, PAGE_SIZE)
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, UserProfile>) {
callback.onResult(userDao.getUserProfileWithLimitAndOffset(PAGE_SIZE, params.key), params.key + PAGE_SIZE)
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, UserProfile>) {
//This one is not used
}
}
如果数据库为空,我已将 BoundaryCallback 设置为从网络获取数据:
class UserProfileBoundaryCallback(val userRepository: RandomUserRepository,
val userDao: UserDao) : PagedList.BoundaryCallback<UserProfile>() {
/**
* Database returned 0 items. We should query the backend for more items.
*/
override fun onZeroItemsLoaded() {
userRepository.getUserProfiles(0, UserProfileDataSource.PAGE_SIZE)
.subscribeOn(Schedulers.io()) //We shouldn't write in the db over the UI thread!
.subscribe(object: DataSourceSubscriber<List<UserProfile>>() {
override fun onResultNext(userProfiles: List<UserProfile>) {
userDao.storeUserProfiles(userProfiles)
}
})
}
/**
* User reached to the end of the list.
*/
override fun onItemAtEndLoaded(itemAtEnd: UserProfile) {
userRepository.getUserProfiles(itemAtEnd.indexPageNumber + 1, UserProfileDataSource.PAGE_SIZE)
.subscribeOn(Schedulers.io()) //We shouldn't write in the db over the UI thread!
.subscribe(object: DataSourceSubscriber<List<UserProfile>>() {
override fun onResultNext(userProfiles: List<UserProfile>) {
userDao.storeUserProfiles(userProfiles)
}
})
}
}
问题是 UI 中的Flowable
或Observable
仅LiveData
在数据来自数据库时触发,当UserProfileDataSource
从数据库返回一些结果时。如果UserProfileDataSource
没有返回任何结果,则调用 BoundaryCallback,成功完成对 API 的请求,将数据存储在数据库中,但Flowable
永远不会触发。如果我关闭应用程序并再次打开它,将获取我们刚刚从数据库中获取的数据,然后将其正确显示。
我已经尝试了在我搜索的所有文章、教程和 github 项目中看到的所有可能的解决方案。
正如我所说,我试图将其更改RxPagedListBuilder
为LivePagedListBuilder
.
使用时,RxPagedListBuilder
我尝试了两者,Flowables
和Observables
.
PagedList.Config.Builder
我尝试为使用不同的调度程序设置不同的配置。
我在这里真的没有选择,我整天都在为此苦苦挣扎,任何提示都将不胜感激。
如果您需要有关代码的更多信息,请给我留言,我会更新帖子。
更新:
我已将完整的源代码提交到我的Github 存储库