Api 呼叫不会停止 一次又一次呼叫 没有任何滚动 Google Paging Library 3
Api call is not stopped calling again and again without any scrolling in Google Paging Library 3
我想实现分页以在我的应用程序中显示我想要的项目视图的一大块列表。这就是为什么我选择使用 Google 新发布的分页库,即 Paging library 3。我在我的应用程序中使用 Rxjava、Livedata 和 ViewModel。
实施分页库后,我遇到了一个奇怪的问题。当我调用获取列表的方法时,它一次又一次地调用并且没有停止调用该调用。事实上,它会自动增加页码,尽管我没有滚动列表。
这是我试过的代码
JobListRestApi.kt
interface JobListRestApi {
@GET("job/list")
fun getJobResponse(
@Query("page") pageNumber: Int
): Single<Response<JobResponse>>
}
JobListDataSource.kt
class JobListDataSource @Inject constructor(
private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
val position = params.key ?: 1
return jobListRestApi.getJobResponse(position).toSingle()
.subscribeOn(Schedulers.io())
.map { jobResponse -> jobResponse.jobData.jobs }
.map { jobs -> toLoadResult(jobs, position) }
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: ArrayList<Job>, position: Int): LoadResult<Int, Job> {
val prevKey = if (position == 1) null else position-1
val nextKey = if (position == data.size) null else position+1
return LoadResult.Page(data, prevKey, nextKey)
}
}
JobListRepositoryImpl.kt
class JobListRepositoryImpl @Inject constructor(
private val jobListDataSource: JobListDataSource
): JobListRepository {
override fun getJobs(): Flowable<PagingData<Job>> {
return Pager(PagingConfig(pageSize = 20)) {
jobListDataSource
}.flowable
}
}
JobListViewModel.kt
class JobListViewModel @Inject constructor(
private val jobListRepository: JobListRepository
): BaseViewModel() {
val jobs: MutableLiveData<PagingData<Job>> = MutableLiveData()
fun getJobs() {
if (jobs.value == null) {
compositeDisposable += jobListRepository.getJobs()
.subscribe({
jobs.value = it
}, {
handleException(it)
})
}
}
}
JobListFragment.kt
class JobListFragment : BaseFragment<JobListViewModel>() {
private val jobAdapter: JobAdapter by lazy {
JobAdapter { }
}
override fun getLayoutResource() = R.layout.fragment_job_list
override fun initWidget() {
job_recycler_view.adapter = jobAdapter
}
override fun onResume() {
super.onResume()
viewModel.getJobs()
}
override fun observeLiveData() {
observe(viewModel.jobs) {
jobAdapter.submitData(lifecycle, it)
}
}
}
输出日志为
https:///base-url/job/list?page=1
https:///base-url/job/list?page=2
https:///base-url/job/list?page=3
https:///base-url/job/list?page=4
https:///base-url/job/list?page=5
https:///base-url/job/list?page=6
https:///base-url/job/list?page=7
如何停止调用串行 api 除非我转到 RecyclerView 中块的最后一项并滚动列表
您通过为 prevKey
返回 null
和 LoadResult.Page
中的 nextKey
来告诉 Paging 没有更多要加载的内容
由于它的无限追加,看起来你从未将 nextKey
设置为 null
。也许您打算检查 data.isEmpty()
而不是 key == data.size
?
最终,我得到了错误。事实上,问题出在我的 Http 响应数据中。更新后的数据源如下所示
JobListDataSource.kt
class JobListDataSource @Inject constructor(
private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
val position = params.key ?: 1
return jobListRestApi.getJobResponse(position).toSingle()
.subscribeOn(Schedulers.io())
.map { jobResponse -> jobResponse.jobData }
.map { jobData -> toLoadResult(jobData, position) }
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: JobData, position: Int): LoadResult<Int, Job> {
val prevKey = if (position == 1) null else position-1
val nextKey = if (data.hasMore) position+1 else null
return LoadResult.Page(data.jobs, prevKey, nextKey)
}
}
我想实现分页以在我的应用程序中显示我想要的项目视图的一大块列表。这就是为什么我选择使用 Google 新发布的分页库,即 Paging library 3。我在我的应用程序中使用 Rxjava、Livedata 和 ViewModel。 实施分页库后,我遇到了一个奇怪的问题。当我调用获取列表的方法时,它一次又一次地调用并且没有停止调用该调用。事实上,它会自动增加页码,尽管我没有滚动列表。 这是我试过的代码
JobListRestApi.kt
interface JobListRestApi {
@GET("job/list")
fun getJobResponse(
@Query("page") pageNumber: Int
): Single<Response<JobResponse>>
}
JobListDataSource.kt
class JobListDataSource @Inject constructor(
private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
val position = params.key ?: 1
return jobListRestApi.getJobResponse(position).toSingle()
.subscribeOn(Schedulers.io())
.map { jobResponse -> jobResponse.jobData.jobs }
.map { jobs -> toLoadResult(jobs, position) }
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: ArrayList<Job>, position: Int): LoadResult<Int, Job> {
val prevKey = if (position == 1) null else position-1
val nextKey = if (position == data.size) null else position+1
return LoadResult.Page(data, prevKey, nextKey)
}
}
JobListRepositoryImpl.kt
class JobListRepositoryImpl @Inject constructor(
private val jobListDataSource: JobListDataSource
): JobListRepository {
override fun getJobs(): Flowable<PagingData<Job>> {
return Pager(PagingConfig(pageSize = 20)) {
jobListDataSource
}.flowable
}
}
JobListViewModel.kt
class JobListViewModel @Inject constructor(
private val jobListRepository: JobListRepository
): BaseViewModel() {
val jobs: MutableLiveData<PagingData<Job>> = MutableLiveData()
fun getJobs() {
if (jobs.value == null) {
compositeDisposable += jobListRepository.getJobs()
.subscribe({
jobs.value = it
}, {
handleException(it)
})
}
}
}
JobListFragment.kt
class JobListFragment : BaseFragment<JobListViewModel>() {
private val jobAdapter: JobAdapter by lazy {
JobAdapter { }
}
override fun getLayoutResource() = R.layout.fragment_job_list
override fun initWidget() {
job_recycler_view.adapter = jobAdapter
}
override fun onResume() {
super.onResume()
viewModel.getJobs()
}
override fun observeLiveData() {
observe(viewModel.jobs) {
jobAdapter.submitData(lifecycle, it)
}
}
}
输出日志为 https:///base-url/job/list?page=1
https:///base-url/job/list?page=2
https:///base-url/job/list?page=3
https:///base-url/job/list?page=4
https:///base-url/job/list?page=5
https:///base-url/job/list?page=6
https:///base-url/job/list?page=7
如何停止调用串行 api 除非我转到 RecyclerView 中块的最后一项并滚动列表
您通过为 prevKey
返回 null
和 LoadResult.Page
nextKey
来告诉 Paging 没有更多要加载的内容
由于它的无限追加,看起来你从未将 nextKey
设置为 null
。也许您打算检查 data.isEmpty()
而不是 key == data.size
?
最终,我得到了错误。事实上,问题出在我的 Http 响应数据中。更新后的数据源如下所示
JobListDataSource.kt
class JobListDataSource @Inject constructor(
private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
val position = params.key ?: 1
return jobListRestApi.getJobResponse(position).toSingle()
.subscribeOn(Schedulers.io())
.map { jobResponse -> jobResponse.jobData }
.map { jobData -> toLoadResult(jobData, position) }
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: JobData, position: Int): LoadResult<Int, Job> {
val prevKey = if (position == 1) null else position-1
val nextKey = if (data.hasMore) position+1 else null
return LoadResult.Page(data.jobs, prevKey, nextKey)
}
}