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

Retrofit搜索结果叠加问题:如何仅显示最新搜索结果?

解决搜索结果追加而非替换的问题

问题描述

通过EditText输入关键词调用API获取新闻数据,首次搜索结果显示正常,但后续搜索时新结果会追加到旧结果的末尾,而非仅展示当前搜索词对应的内容。尝试添加@Headers("Cache-Control: no-cache")解决缓存问题,但无效。

问题根源

问题并非网络缓存导致,而是客户端的列表状态管理逻辑存在漏洞:

  • ViewModel发起新搜索时,未正确重置之前的结果状态,导致旧数据未被清空
  • 未处理搜索词为空的场景,旧列表持续保留

修复步骤

1. 完善ViewModel的搜索状态重置逻辑

在发起新搜索请求前,先发送Loading状态,确保后续的Success状态携带全新结果,覆盖旧数据。补全ViewModel核心代码:

class NewsViewModel : ViewModel() {
    private val _searchNews = MutableLiveData<Resource<NewsResponse>>()
    val searchNews: LiveData<Resource<NewsResponse>> = _searchNews

    fun searchNews(query: String) {
        // 新搜索发起时重置状态,通知UI开始加载
        _searchNews.postValue(Resource.Loading())
        viewModelScope.launch {
            try {
                val response = newsRepository.searchNews(query)
                if (response.isSuccessful) {
                    // 提交全新的搜索结果
                    _searchNews.postValue(Resource.Success(response.body()))
                } else {
                    _searchNews.postValue(Resource.Error("搜索请求失败"))
                }
            } catch (e: Exception) {
                _searchNews.postValue(Resource.Error(e.message ?: "未知错误"))
            }
        }
    }
}

2. 处理搜索词为空的场景

在Fragment的文本监听中,当搜索词为空时直接清空列表:

var job: Job? = null
binding.etSearchNews.addTextChangedListener { editable ->
    job?.cancel()
    job = MainScope().launch {
        delay(Constants.SEARCH_DELAY)
        val query = editable.toString().trim()
        if (query.isNotEmpty()) {
            viewModel.searchNews(query)
        } else {
            // 搜索词为空时清空列表
            newsAdapter.differ.submitList(emptyList())
        }
    }
}

3. 确保Adapter正确替换列表

当前代码中response.articles.toList()已经生成新列表实例,但如果仍存在追加问题,可临时在收到成功结果时先提交空列表再提交新列表(仅用于排查,正常情况下无需此操作):

viewModel.searchNews.observe(viewLifecycleOwner) {
    when (it) {
        is Resource.Success -> {
            hideProgressBar()
            it.data?.let { response ->
                newsAdapter.differ.submitList(emptyList())
                newsAdapter.differ.submitList(response.articles.toList())
            }
        }
        is Resource.Error -> {
            hideProgressBar()
            // 可添加错误提示逻辑
        }
        is Resource.Loading -> {
            showProgressBar()
        }
    }
}

4. 验证API请求参数

确认Retrofit接口每次请求都携带了最新的搜索词,当前你的API代码已经正确传入@Query("q") query参数,这部分无需修改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:05:38