如何实现SearchView对虚拟Materi数据的标题搜索功能?
解决SearchView匹配Materi标题的实现方案
核心思路
先保存完整的原始数据集,监听SearchView的输入变化,实时过滤出标题包含搜索文本的Materi数据,再提交给RecyclerView适配器更新列表。
具体修改步骤
1. 在MateriFragment中保存原始数据集
在Fragment类中添加变量存储所有原始Materi数据,避免每次搜索重复从数据源获取:
class MateriFragment : Fragment() { // 新增:保存原始数据集 private var originalMateriList: List<Materi> = emptyList() // 原有的其他变量... private fun setupList() { val span = if(adapter.adapterLayoutMode == AdapterLayoutMode.LINEAR) 1 else 2 binding.rvMateri.apply { layoutManager = GridLayoutManager(requireContext(),span) adapter = this@MateriFragment.adapter } // 初始化原始数据集并提交给适配器 originalMateriList = datasource.getMateriData(requireContext()) adapter.setItems(originalMateriList) } // 原有的其他方法... }
2. 实现SearchView的搜索逻辑
补全setSearchView方法,绑定SearchView并编写过滤逻辑:
private fun setSearchView() { binding.searchView.apply { // 设置搜索提示文本(可选) queryHint = "搜索标题..." // 监听搜索文本变化 setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { query?.let { filterMateriList(it) } clearFocus() // 收起软键盘 return true } override fun onQueryTextChange(newText: String?): Boolean { newText?.let { filterMateriList(it) } return true } }) } } // 新增:过滤数据集的方法 private fun filterMateriList(searchText: String) { val filteredList = if (searchText.isBlank()) { // 搜索文本为空时显示全部原始数据 originalMateriList } else { // 过滤标题包含搜索文本的项,忽略大小写提升体验 originalMateriList.filter { materi -> materi.title.contains(searchText, ignoreCase = true) } } // 提交过滤后的结果给适配器 adapter.setItems(filteredList) }
3. 初始化搜索功能
在Fragment视图创建完成后调用setSearchView:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupList() setupSwitch() setSearchView() // 新增:初始化搜索功能 }
关键说明
- 忽略大小写匹配:使用
contains(searchText, ignoreCase = true)让搜索不区分大小写,提升用户体验。 - 复用原始数据集:每次过滤都基于原始数据,避免多次过滤导致数据丢失。
- 高效更新列表:你的适配器已使用
AsyncListDiffer,提交过滤后的列表时会自动计算差异并高效更新RecyclerView,无需手动调用notifyDataSetChanged。
内容的提问来源于stack exchange,提问作者ryhanhxx
相关产品推荐
相关产品推荐

