如何过滤Remote Flow列表:仅展示未存入Local Room数据库的项
解决方案:本地更新时自动过滤远程列表
你当前的问题核心在于:过滤逻辑仅绑定了remoteFlow的变化,没有监听localFlow的更新。当本地数据库新增数据时,localFlow会发送新值,但因为你的过滤代码是在remoteFlow.map里执行的,只有remoteFlow发送新值时才会重新计算过滤结果,所以本地更新后远程列表不会自动变化。
正确的实现方式是同时监听remoteFlow和localFlow的变化,让任意一个流更新时都重新执行过滤逻辑。直接用combine合并两个流,在合并的转换函数中完成过滤:
val uiState = combine(remoteFlow, localFlow) { remoteList, localList -> // 过滤出未存入本地的远程项 val filteredRemote = remoteList.filter { remoteItem -> localList.none { it.id == remoteItem.id } } JobListUiState(filteredRemote, localList) }.stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000L), initialValue = JobListUiState() )
优化建议(针对大数据量场景)
如果本地列表数据较多,直接用none遍历比较会影响性能,可以先把本地数据的ID转换成Set,再做判断,提升过滤效率:
val uiState = combine(remoteFlow, localFlow) { remoteList, localList -> // 将本地ID转为Set,O(1)时间复杂度判断存在性 val localIds = localList.mapTo(mutableSetOf()) { it.id } val filteredRemote = remoteList.filter { it.id !in localIds } JobListUiState(filteredRemote, localList) }.stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000L), initialValue = JobListUiState() )
这样修改后,无论是远程数据刷新,还是本地数据库新增/删除数据,combine都会触发重新计算,自动更新过滤后的远程列表,完全满足你的需求。
内容的提问来源于stack exchange,提问作者OndraVojta
相关产品推荐
相关产品推荐

