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

如何修复Jetpack Compose加密货币列表的搜索功能?

修复加密货币列表应用的搜索功能

问题根源

当前搜索功能失效的核心原因:

  • UI展示依赖viewModel.state.value.coins,但搜索函数操作的是独立的coinsList变量,数据源不统一导致搜索结果无法同步到UI
  • API加载数据后,搜索相关的缓存列表未同步真实数据,导致搜索时无有效数据可过滤

修复步骤

1. 调整状态数据类结构

将缓存列表整合到CoinListState中,确保数据源统一:

data class CoinListState(
    val isLoading: Boolean = false,
    val coins: List<Coin> = emptyList(),
    val cachedCoins: List<Coin> = emptyList(),
    val error: String = ""
)

2. 重写ViewModel的搜索逻辑

更新ViewModel,同步API数据到缓存列表,修改过滤规则(支持排名部分匹配),并直接更新UI绑定的状态字段:

@HiltViewModel
class CoinListViewModel @Inject constructor(
    private val getCoinsUseCase: GetCoinsUseCase,
) : ViewModel() {

    private val _state = mutableStateOf(CoinListState())
    val state: State<CoinListState> = _state

    init {
        getCoins()
    }

    fun searchCoinsList(query: String) {
        viewModelScope.launch(Dispatchers.Default) {
            val trimmedQuery = query.trim()
            // 优先使用缓存的完整数据作为搜索源
            val searchSource = _state.value.cachedCoins.ifEmpty { _state.value.coins }

            val filteredCoins = if (trimmedQuery.isEmpty()) {
                // 清空搜索时恢复完整列表
                _state.value.cachedCoins.ifEmpty { _state.value.coins }
            } else {
                searchSource.filter { coin ->
                    // 匹配名称(忽略大小写)、排名(支持部分数字匹配)、符号(忽略大小写)
                    coin.name.contains(trimmedQuery, ignoreCase = true) ||
                    coin.rank.toString().contains(trimmedQuery) ||
                    coin.symbol.contains(trimmedQuery, ignoreCase = true)
                }
            }

            // 更新UI状态
            _state.value = _state.value.copy(coins = filteredCoins)
        }
    }

    private fun getCoins() {
        getCoinsUseCase().onEach { result ->
            when (result) {
                is Resource.SUCCESS -> {
                    val coinList = result.data ?: emptyList()
                    _state.value = CoinListState(
                        coins = coinList,
                        cachedCoins = coinList // 初始化完整数据缓存
                    )
                }
                is Resource.ERROR -> {
                    _state.value = CoinListState(
                        error = result.message ?: "An unexpected error occurred"
                    )
                }
                is Resource.LOADING -> {
                    _state.value = CoinListState(isLoading = true)
                }
            }
        }.launchIn(viewModelScope)
    }
}

3. 功能验证

修改后搜索功能可正常工作:

  • 输入币种名称(如Bitcoin)会匹配包含该名称的结果
  • 输入排名数字(如1或10)会匹配排名包含对应数字的币种
  • 输入币种符号(如BTC)会匹配包含该符号的结果
  • 清空搜索框会自动恢复展示完整币种列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:45:29