如何基于ViewModel中LiveData存储的已有数据实现搜索筛选功能
实现方案
你需要先缓存全量的原始联赛数据,避免过滤后丢失原始数据源,导致后续搜索无法恢复全量数据:
第一步:新增全量数据缓存变量
在ViewModel中新增私有变量存储接口返回的完整联赛列表:
// 缓存接口返回的全量联赛数据 private var allLeagues: List<Response> = emptyList()
修改getLeaguesBySeasons方法,拿到数据后先赋值给这个缓存变量:
list?.let { allLeagues = it // 新增这行缓存全量数据 _response.postValue(Resource.success(it)) }
第二步:编写onFilterLeague过滤逻辑
逻辑处理规则:
- 搜索词为空/全是空白时,直接返回全量联赛数据
- 有搜索词时,按联赛名称(可根据你的Response实际字段调整)模糊匹配,忽略大小写
- 过滤后结果为空时可根据需求抛出事件提示用户无匹配结果
代码如下:
fun onFilterLeague(query: String) { viewModelScope.launch(Dispatchers.Default) { // 全量数据还未加载完成时直接返回 if (allLeagues.isEmpty()) { return@launch } val filterResult = if (query.isBlank()) { // 搜索词为空返回全量数据 allLeagues } else { val lowerQuery = query.trim().lowercase() allLeagues.filter { league -> // 这里的name需要替换为你Response实体类中对应的联赛名称字段 league.name.lowercase().contains(lowerQuery) // 如需多字段匹配可追加条件,比如同时匹配联赛所属国家:|| league.country.lowercase().contains(lowerQuery) } } // 把过滤结果更新到LiveData通知UI刷新 _response.postValue(Resource.success(filterResult)) // 可选:无匹配结果时发送事件给UI做提示 if (filterResult.isEmpty() && query.isNotBlank()) { _events.postValue(Event("暂无匹配的联赛")) } } }
注意事项
- 过滤操作放在
Dispatchers.Default线程执行,避免数据量大时阻塞主线程 - 代码中用到的Response实体类字段需要替换为你实际定义的对应字段
- 如果需要支持拼音搜索、首字母搜索等能力,需要额外引入拼音转换库处理字段后再做匹配
内容的提问来源于stack exchange,提问作者Thang
相关产品推荐
相关产品推荐

