提交新分页搜索数据时如何清除PagingDataAdapter的旧数据?
可行解决方案
你可以通过以下两种常用方案实现需求:
方案1:搜索触发时主动清空旧数据(推荐)
每次搜索词变更时先向适配器传入空PagingData清除旧数据,此时adapter.itemCount变为0,新搜索的加载状态自然会触发全屏占位符逻辑。
调整ViewModel代码
修改itemsStream的流构建逻辑,每次切换搜索请求前先发射空分页数据:
val itemsStream: LiveData<PagingData<Item>> = searchTextStream .debounce(Duration.milliseconds(400)) .flatMapLatest { val filter = ItemsFilter(name = it) // 先发射空PagingData触发旧数据清空,再发射真实请求流 flowOf(PagingData.empty<Item>(), getItemsStreamUseCase(filter)) } .cachedIn(viewModelScope) .asLiveData()
该方案无需修改原有加载状态判断逻辑,兼容性最好。
方案2:新增搜索状态标记修正判断逻辑
如果你需要保留旧搜索结果直到新结果返回再替换,可以单独维护搜索中状态,调整加载逻辑的判断条件:
- ViewModel新增搜索状态流
private val isSearching = MutableStateFlow(false) val isSearchingStream: StateFlow<Boolean> = isSearching.asStateFlow() val itemsStream: LiveData<PagingData<Item>> = searchTextStream .debounce(Duration.milliseconds(400)) .onEach { isSearching.value = true } .flatMapLatest { val filter = ItemsFilter(name = it) getItemsStreamUseCase(filter) .onEach { isSearching.value = false } .catch { isSearching.value = false } } .cachedIn(viewModelScope) .asLiveData()
- 修改Fragment的加载状态判断逻辑
adapter.loadStateFlow .onEach { loadState -> val isSearching = viewModel.isSearchingStream.value val isRefreshing = loadState.refresh is LoadState.Loading val showLoadingPlaceholder = (isRefreshing && adapter.itemCount < 1) || isSearching val showSwipeRefreshIndicator = isRefreshing && adapter.itemCount > 0 && !isSearching // 其余原有逻辑 } .launchIn(viewLifecycleOwner.lifecycleScope)
注意事项
如果采用方案1,无需改动Fragment的观察逻辑,空PagingData会自动触发适配器清空原有条目,后续新的分页数据加载时就会正确展示全屏加载占位符。
内容的提问来源于stack exchange,提问作者mickp
相关产品推荐
相关产品推荐

