在我的用户界面中,我有一个recyclerview和一个chip group。每个chip代表不同的调用来更新。当我点击一个chip时,我希望recyclerview会消失,直到加载新数据。RV确实消失了,但是当它再次显示时,它显示旧数据不到一秒钟,然后才改变为新数据。作为参考,我使用了paging codelab-〉www.example.comhttps://developer.android.com/codelabs/android-paging#0
我该怎么修呢?
碎片
我观察分页数据和负载状态如下:
viewLifecycleOwner.lifecycleScope.launch {
pagingData.collectLatest(customAdapter::submitData)
}
viewLifecycleOwner.lifecycleScope.launch {
customAdapter.loadStateFlow.collect { loadState ->
header.loadState = loadState.mediator
?.refresh
?.takeIf { it is LoadState.Error && customAdapter.itemCount > 0 }
?: loadState.prepend
val isListEmpty = loadState.refresh is LoadState.NotLoading && customAdapter.itemCount == 0
emptyList.isVisible = isListEmpty
recyclerView.isVisible = loadState.mediator?.refresh is LoadState.NotLoading || loadState.source.refresh is LoadState.NotLoading
progressBar.isVisible = loadState.mediator?.refresh is LoadState.Loading
retryButton.isVisible = loadState.mediator?.refresh is LoadState.Error && customAdapter.itemCount == 0
val errorState = loadState.source.append as? LoadState.Error
?: loadState.source.prepend as? LoadState.Error
?: loadState.append as? LoadState.Error
?: loadState.prepend as? LoadState.Error
errorState?.let {
Toast.makeText(
requireContext(),
"\uD83D\uDE28 Wooops ${it.error}",
Toast.LENGTH_LONG
).show()
}
}
}
下面是我如何更改类别:
chip1.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch {
onCategoryChanged(CustomAction.ChangeCategory(category = CustomCategory.A))
}
}
chip2.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch {
customAdapter.refresh()
onCategoryChanged(CustomAction.ChangeCategory(category = CustomCategory.B))
}
}
视图模型
下面是我如何根据视图模型中的状态类别更新分页数据:
val actionStateFlow = MutableSharedFlow<CustomAction>()
val changedCategory = actionStateFlow
.filterIsInstance<CustomAction.ChangeCategory>()
.distinctUntilChanged()
.onStart { emit(CustomAction.ChangeCategory(category = initialCategory)) }
pagingDataFlow = state
.flatMapLatest {
when (it.category) {
CustomCategory.A -> searchA(query = it.query)
CustomCategory.B -> searchB(query = it.query)
}
}
.cachedIn(viewModelScope)
private fun searchA(query: String): Flow<PagingData<CustomItem>> {
return repository.getA(query = query).map { pagingData ->
pagingData.map { it.mapToDomainModel() }
}
}
private fun searchB(query: String): Flow<PagingData<CustomItem>> {
return repository.getB(query = query).map { pagingData ->
pagingData.map { it.mapToDomainModel() }
}
}
1条答案
按热度按时间7lrncoxx1#
我假设您使用的是
RemoteMediator
,这似乎是Paging3库的预期功能(尽管违反直觉)。答案就在下面这段文档中:
RemoteMediator实现还可以覆盖initialize()方法,以检查缓存数据是否过期,并决定是否触发远程刷新。此方法在执行任何加载之前运行,因此您可以在触发任何本地或远程加载之前操作数据库(例如,清除旧数据)。
我自己做了它,使
initialize()
方法总是返回LAUNCH_INITIAL_REFRESH
,我以为这将总是使寻呼机"从头开始",但似乎如果有东西缓存在数据库中,它仍然会显示该数据,然后触发刷新,这反过来应该清除数据库中的所有数据,并插入新的。RemoteMediator
的initialize()
方法中,清除缓存项目的数据库。