我用过 Jetpack 的 Paging 3我的项目中用于处理数据分页的库。我有一个用例,当用户在搜索请求中更改某些内容(例如添加/删除一些过滤器)时,我必须调用 API 并根据新的搜索请求用新数据重新填充我的列表。但是当我创建新的 Pager
实例并将其传递给我的PagingDataAdapter
适配器,它抛出:
java.lang.IllegalStateException: Collecting from multiple PagingData concurrently is an illegal operation.
我的实现是这样的:存储库
class Repository {
fun getDataStream(request: Request): Flow<PagingData<Response>> {
return Pager(
config = PagingConfig(
pageSize = 10,
initialLoadSize = 10,
prefetchDistance = 3
),
initialKey = 1,
pagingSourceFactory = {
DataPagingSource(
request = request,
repository = this
)
}
).flow
}
fun getData(page: Int, request: Request): Result<Response> {
return remoteDataSource.getData(page, request)
}
}
数据分页源 class DataPagingSource(
private val request: Request,
private val repository: Repository
) : PagingSource<Int, Response>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Response> {
val page = params.key ?: 1
// Result is a sealed class which has two derived classes: Success and Error
return when (val result = repository.getData(page, request)) {
is Result.Success -> {
LoadResult.Page(
data = result.data,
nextKey = page.inc(),
prevKey = null
)
}
is Result.Error -> LoadResult.Error(
result.error
)
}
}
}
查看型号 class SomeViewModel(
private val repository: Repository
): ViewModel() {
private val _currentRequest = MutableLiveData<Request>()
val data = _currentRequest
.switchMap {
repository
.getDataStream(it)
.cachedIn(viewModelScope)
.asLiveData()
}
fun updateRequest(request: Request) {
_currentRequest.postValue(request)
}
}
fragment class SomeFragment: Fragment() {
private lateinit var viewModel: SomeViewModel
// ...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// ...
viewModel.data.observe(
viewLifecycleOwner,
Observer {
lifecycleScope.launch {
adapter.submitData(it)
}
}
)
}
// ...
}
如果有人帮助解决这个问题,那就太好了。谢谢
最佳答案
我相信如果您将寻呼机作为 LiveData 进行观察,您需要使用 adapter.submitData(lifecycle, data)方法而不是 adapter.submitData(data)在您的 Fragment 中,虽然我也建议尝试 distinctUntilChanged()对您的 _currentRequest LiveData 进行转换,以限制从重复请求创建多个 PagingData 对象。
submitData(lifecycle: Lifecycle, pagingData: PagingData) 文档
This method is typically used when observing a RxJava or LiveData stream produced by Pager. For Flow support, use the suspending overload of submitData, which automates cancellation via CoroutineScope instead of relying of Lifecycle
https://developer.android.com/reference/kotlin/androidx/paging/PagingDataAdapter#submitdata_1
fragment
viewModel.data.observe(
viewLifecycleOwner,
Observer {
adapter.submitData(lifecycle, it)
}
)
查看型号 val data = _currentRequest
// Limit duplicate Requests (Request class should implement equals())
.distinctUntilChanged()
.switchMap {
// ...
}
关于android - 使用 Paging3 库时更改请求并获取新数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62554267/