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

Kotlin实现RecyclerView搜索功能后旧数据残留,如何仅展示新查询数据?

问题根因

你的代码最大的问题是混用Navigation组件和手动Fragment事务,导致新旧Fragment的RecyclerView视图叠加,看起来像数据残留:

  • 你已经通过setupActionBarWithNavController、navView.setupWithNavController将导航逻辑交给了Navigation组件管理,R.id.nav_host_fragment是Navigation组件的宿主容器,内部Fragment的生命周期由NavController统一管控
  • 你点击搜索按钮时直接调用supportFragmentManager.beginTransaction().replace()修改NavHost内部的容器内容,会和Navigation本身的栈管理逻辑冲突,旧的Fragment视图没有被完全销毁,和新创建的RecordFragment的RecyclerView重叠展示,就出现了新数据叠在旧数据上的现象

修复方案

方案1:改用Navigation组件跳转(推荐)

  1. 首先在你的导航图xml文件中,给RecordFragment对应的目的地添加参数配置:
<fragment
    android:id="@+id/recordFragment"
    android:name="你的包名.RecordFragment">
    <argument
        android:name="parameter"
        app:argType="string"
        android:defaultValue="A" />
</fragment>
  1. 修改MainActivity中搜索按钮的点击逻辑,用NavController跳转而非手动replace Fragment:
binding.btnSearch.setOnClickListener {
    val searchKey = if (binding.etSearch.text.isEmpty()) {
        "A"
    } else {
        binding.etSearch.text.toString()
    }
    val bundle = bundleOf("parameter" to searchKey)
    findNavController(R.id.nav_host_fragment).navigate(R.id.recordFragment, bundle)
}

方案2:如果坚持用手动Fragment事务

需要先将NavHost中默认存在的初始Fragment全部移除,再添加新的RecordFragment,同时可以给RecyclerView设置非透明背景避免透色:

binding.btnSearch.setOnClickListener {
    val recordFragment = RecordFragment()
    val bundle = Bundle()
    val searchKey = if (binding.etSearch.text.isEmpty()) {
        "A"
    } else {
        binding.etSearch.text.toString()
    }
    bundle.putString("parameter", searchKey)
    recordFragment.arguments = bundle
    // 先清空NavHost容器内所有已有Fragment
    supportFragmentManager.fragments.forEach { 
        supportFragmentManager.beginTransaction().remove(it).commit() 
    }
    // 再添加新的Fragment
    supportFragmentManager.beginTransaction()
        .replace(R.id.nav_host_fragment, recordFragment)
        .commit()
}

适配器优化(可选)

你的setList方法存在空指针风险,可以优化空判断逻辑,同时将列表声明为非空减少后续冗余判断:

// 把mRecord从可空改成非空
private val mRecord = arrayListOf<Event>()

@SuppressLint("NotifyDataSetChanged")
fun setList(data: List<Event>?) {
    mRecord.clear()
    data?.let {
        mRecord.addAll(it)
    }
    notifyDataSetChanged()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:57:00