You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中基于Flow<List<Item>>实现搜索过滤

解决方案

你的代码存在几个问题导致搜索过滤不生效,我来一步步修正并实现正确的搜索逻辑:

1. 先实现Item的名称匹配逻辑

首先给Item类添加一个用于判断是否匹配搜索文本的方法,建议忽略大小写提升用户体验:

data class Item(
    @PrimaryKey
    val id: Int? = null,
    val firstName: String,
    val middleName: String,
    val lastName: String,
) {
    // 判断当前Item是否匹配搜索文本
    fun matchesSearchText(text: String): Boolean {
        val lowerCaseText = text.lowercase()
        return firstName.lowercase().contains(lowerCaseText) ||
                middleName.lowercase().contains(lowerCaseText) ||
                lastName.lowercase().contains(lowerCaseText)
    }
}

2. 重构ViewModel的搜索逻辑

原代码中直接重新赋值itemList的方式不合理,而且onEach操作符不会修改Flow发射的数据(它只是执行副作用)。正确的做法是用combine操作符将原始的Item列表Flow和搜索文本Flow结合,自动完成过滤:

class ItemListViewModel @Inject constructor(
    private val repository: ItemRepository
): ViewModel() {
    // 原始的全量Item列表Flow,只获取一次
    private val allItemsFlow = repository.getAllItem()
    
    private val _searchText = MutableStateFlow("")
    val searchText: StateFlow<String> = _searchText.asStateFlow()

    // 结合搜索文本和全量列表,动态生成过滤后的列表
    val itemList: StateFlow<List<Item>> = combine(allItemsFlow, searchText) { items, text ->
        if (text.isBlank()) {
            items // 搜索文本为空时返回全量列表
        } else {
            items.filter { it.matchesSearchText(text) }
        }
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000), // 优化订阅生命周期
        initialValue = emptyList()
    )

    fun onSearchTextChange(text: String) {
        _searchText.value = text.trim() // 去除首尾空格,避免无效搜索
    }
}

关键改进点说明

  • 用combine自动监听两个Flow的变化:当搜索文本或者原始列表更新时,自动重新过滤,无需手动分支判断
  • 将itemList转为StateFlow并通过stateIn在ViewModel中持有,确保UI能稳定收集数据,不会因为Flow实例变更导致重复订阅
  • 简化onSearchTextChange逻辑,只需要更新搜索文本即可,过滤逻辑统一交给combine处理
  • 匹配逻辑忽略大小写,提升用户体验

这样修改后,UI只要收集itemList这个StateFlow,就能自动根据搜索文本展示匹配的Item列表了。

内容的提问来源于stack exchange,提问作者sujan_014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:12:53