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

如何在RecyclerViewAdapter中实现按名称搜索筛选功能

实现按猫咪名称筛选的具体方案

第一步:修改RecyclerViewAdapter,添加筛选逻辑

首先我们需要在Adapter中保存完整的原始数据集,同时实现Android原生的Filterable接口处理筛选逻辑,修改后的Adapter代码如下:

class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>(), Filterable {

    // 展示用的数据集(筛选后)
    private var items = ArrayList<CatBreed>()
    // 原始完整数据集,筛选时作为数据源
    private val originalItems = ArrayList<CatBreed>()
    var onItemClick: ((CatBreed) -> Unit)? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding = CatBreedRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MyViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(items[position])
        holder.itemView.setOnClickListener {
            Log.d("adapter", "item clicked")
            onItemClick?.invoke(items[position])
        }
    }

    override fun getItemCount(): Int {
        return items.size
    }

    fun setUpdatedData(items: ArrayList<CatBreed>) {
        // 同时更新展示数据集和原始数据集
        this.items.clear()
        this.items.addAll(items)
        this.originalItems.clear()
        this.originalItems.addAll(items)
        notifyDataSetChanged()
    }

    // 重写Filterable接口的方法,返回自定义筛选器
    override fun getFilter(): Filter {
        return object : Filter() {
            // 后台线程执行筛选逻辑
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val filteredList = if (constraint.isNullOrEmpty()) {
                    // 搜索关键词为空,返回全部原始数据
                    originalItems
                } else {
                    val filterPattern = constraint.toString().lowercase().trim()
                    // 筛选名称包含关键词的条目,忽略大小写
                    originalItems.filter { it.name.lowercase().contains(filterPattern) } as ArrayList<CatBreed>
                }
                val results = FilterResults()
                results.values = filteredList
                return results
            }

            // 主线程更新筛选后的展示数据
            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                items.clear()
                items.addAll(results?.values as ArrayList<CatBreed>)
                notifyDataSetChanged()
            }
        }
    }

    inner class MyViewHolder(private val binding: CatBreedRowBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(data: CatBreed) {
            binding.tvName.text = data.name

            Picasso.get()
                .load(data.image.url)
                .into(binding.imageThumb)
        }
    }
}

第二步:配置搜索菜单,关联Adapter筛选逻辑

首先确保你的res/menu/menu_item.xml中的搜索项配置了SearchView作为动作视图,示例配置如下:

<item
    android:id="@+id/action_search"
    android:title="搜索"
    android:icon="@drawable/ic_search"
    app:showAsAction="ifRoom|collapseActionView"
    app:actionViewClass="android.widget.SearchView" />

然后修改MainActivity的onCreateOptionsMenu方法,添加搜索框的文本变化监听,调用Adapter的筛选方法:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_item, menu)
    // 找到搜索菜单项
    val searchItem = menu.findItem(R.id.action_search)
    val searchView = searchItem.actionView as SearchView
    // 设置搜索提示
    searchView.queryHint = "输入猫咪名称搜索"
    
    // 监听搜索框文本变化
    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        // 提交搜索时触发
        override fun onQueryTextSubmit(query: String?): Boolean {
            adapter.filter.filter(query)
            return true
        }
        // 搜索框文本变化时实时触发
        override fun onQueryTextChange(newText: String?): Boolean {
            adapter.filter.filter(newText)
            return true
        }
    })
    return true
}

注意:上面代码中的adapter要替换为你在MainActivity中实际声明的RecyclerViewAdapter实例变量名。

可选优化

如果需要更高的列表更新性能,可以把notifyDataSetChanged()替换为DiffUtil计算差异后局部刷新,避免整个列表重绘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:36:00