データのページネーションを処理するために、プロジェクトで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)
}
}
DataPagingSource
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)
}
}
断片
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)
}
}
)
}
// ...
}
誰かがこの問題を解決するのを手伝ってくれれば、それは素晴らしいことです.
ありがとうございました