android - 使用 Paging3 库时更改请求并获取新数据流

标签 android android-paging android-paging-library

我用过 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/

相关文章:

android - 为什么我的 PagingSource 没有给我任何数据?

android - 从 Assets 中读取 unicode 文本

java - 通过过滤显示或隐藏 HashMap 标记

android - 如何正确包含 1 0"and 7"布局

Android分页边界回调说明

android - 在 Repository 类中观察 Forever 是一个好习惯吗? db+network 分页列表

java - 尝试使用 Maps API 查找附近地点时出现 FileNotFoundException

android - PagedListAdapter.submitList() 在更新现有项目时表现异常

android - 使用分页库显示加载指示器

android - Paging 3 - 如何在 PagingDataAdapter 完成刷新并且 DiffUtil 完成差异后滚动到 RecyclerView 的顶部?