Android Kotlin:如何通过LiveData<String>过滤Room返回的LiveData<Map>?
Kotlin中过滤Room返回的LiveData<Map<Server, List>>数据
你可以通过组合两个LiveData(数据源和搜索关键词),在数据变化时执行过滤逻辑来实现需求。核心思路是:监听数据源和搜索词的更新,对每个Server下的Group列表进行筛选,只保留描述包含搜索关键词的Group,同时移除过滤后无Group的Server条目。
数据类定义
data class Server( val serverId: Int ) data class Group( val serverId: Int, val groupId: Int, val description: String )
实现方案
使用MediatorLiveData监听两个LiveData的变化,任一数据更新时自动执行过滤操作:
import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.LiveData // 从Room获取的数据源 val serverGroupsLiveData: LiveData<Map<Server, List<Group>>> = ... // 搜索关键词LiveData val searchQueryLiveData: LiveData<String> = ... // 过滤后的结果LiveData val filteredServerGroupsLiveData: LiveData<Map<Server, List<Group>>> = MediatorLiveData<Map<Server, List<Group>>>().apply { // 封装过滤逻辑 fun filterData(serverGroups: Map<Server, List<Group>>?, query: String?): Map<Server, List<Group>> { val lowerCaseQuery = query?.trim()?.lowercase() ?: "" return serverGroups?.mapValues { (_, groups) -> groups.filter { group -> group.description.lowercase().contains(lowerCaseQuery) } }?.filterValues { it.isNotEmpty() } ?: emptyMap() } // 监听数据源变化 addSource(serverGroupsLiveData) { value = filterData(it, searchQueryLiveData.value) } // 监听搜索词变化 addSource(searchQueryLiveData) { value = filterData(serverGroupsLiveData.value, it) } }
逻辑说明
- 大小写兼容:将搜索词和Group描述统一转为小写,实现不区分大小写的搜索(如需区分大小写,移除
lowercase()即可)。 - Group筛选:对每个Server对应的Group列表,保留描述包含搜索关键词的条目。
- 清理空条目:过滤后移除无Group的Server,避免显示空Server项。
- 实时更新:数据源或搜索词发生变化时,自动重新计算并发布最新结果。
简化写法(依赖lifecycle-livedata-ktx)
如果项目引入androidx.lifecycle:lifecycle-livedata-ktx,可以用combine函数简化实现:
import androidx.lifecycle.liveData import androidx.lifecycle.combine val filteredServerGroupsLiveData = liveData { combine(serverGroupsLiveData, searchQueryLiveData) { serverGroups, query -> val lowerCaseQuery = query.trim().lowercase() serverGroups.mapValues { (_, groups) -> groups.filter { it.description.lowercase().contains(lowerCaseQuery) } }.filterValues { it.isNotEmpty() } }.collect { emit(it) } }
内容的提问来源于stack exchange,提问作者james04
相关产品推荐
相关产品推荐

