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

RecyclerView过滤器异常排查:删除搜索内容后列表未恢复原数据

过滤器逻辑错误分析与修复方案

核心问题

过滤器清空搜索内容后无法恢复原始列表,根源是没有保留完整的原始数据源,且过滤操作直接覆盖了适配器的数据源,导致清空时只能拿到已过滤后的子集。

具体逻辑漏洞

  • 适配器的transactions属性通过getGroup(1)获取值,但每次过滤后调用submitGroup(1, transactionsFiltered, true)会直接修改分组1的数据源。后续transactions getter返回的是过滤后的列表,而非初始的完整数据。
  • 在performFiltering中,当搜索内容为空时,你试图用transactions(此时已是过滤后的数据)恢复列表,自然无法回到初始状态。
  • 初始化transactionsFiltered时仅用了构造函数传入的初始transactions,但后续外部更新transactions时,没有同步更新这个基准数据源。

修复方案

1. 保存原始完整数据源

在适配器中新增一个变量存储初始的完整交易列表,作为过滤操作的基准:

class TransactionsAdapter(
    // ... 其他构造参数
    transactions: List<Transaction> = emptyList(),
    // ...
) : DynamicListAdapter<...>(...) {
    // 保存原始完整数据源,避免外部修改影响
    private var originalTransactions: List<Transaction> = transactions.toList()
    
    var transactions: List<Transaction>
        get() = getGroup(1)
        set(value) {
            submitGroup(1, value, true)
            // 外部更新数据源时同步更新原始基准
            originalTransactions = value.toList()
        }
    
    // 初始化过滤列表为原始数据源
    private var transactionsFiltered: List<Transaction> = originalTransactions
    
    // ... 其他代码
}

2. 修改过滤逻辑,基于原始数据源操作

更新Filter的performFiltering方法,清空搜索时直接使用原始数据源恢复:

override fun getFilter(): Filter = object : Filter() {
    override fun performFiltering(constraint: CharSequence?): FilterResults {
        val charString = constraint?.toString() ?: ""
        transactionsFiltered = if (charString.isEmpty()) {
            // 清空搜索时用原始完整数据源
            originalTransactions
        } else {
            originalTransactions.filter {
                it.name.contains(charString, true) || it.value.toString().contains(charString)
            }
        }
        return FilterResults().apply { values = transactionsFiltered }
    }

    override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
        transactionsFiltered = results?.values as? List<Transaction> ?: emptyList()
        submitGroup(1, transactionsFiltered, true)
        notifyDataSetChanged()
    }
}

额外优化

  • 移除performFiltering中多余的ArrayList转换,直接使用filter返回的列表即可,简化代码。
  • 确保originalTransactions始终是不可变的副本(用toList()),避免外部修改原始列表导致基准数据异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:07:00