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

如何在RecyclerView中高亮显示SearchView输入的过滤文本?

实现RecyclerView搜索结果高亮的完整方案

我来帮你搞定这个搜索文本高亮的问题!你之前在ViewHolder里尝试没生效,核心原因是没有把搜索文本传递到Adapter中,也没对TextView的文本做 Spannable 富文本处理。下面是一步步的修改方案:

第一步:修改你的BookAdapter,添加高亮逻辑

我们需要给Adapter增加存储搜索文本的变量,再写一个工具方法来生成带高亮效果的文本,最后在bind方法里替换原有的文本设置逻辑。

修改后的bookadapter.kt代码:

class bookadapter(
    private var booklist: ArrayList<Booksmodel>,
    private val itemClickListener: OnItemClicklistner
) : RecyclerView.Adapter<bookadapter.bookholder>() {
    // 新增:存储搜索文本
    private var searchText: String = ""

    // 新增:设置搜索文本的方法
    fun setSearchText(text: String) {
        this.searchText = text.lowercase(Locale.getDefault())
        notifyDataSetChanged() // 更新UI
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): bookholder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.singlebook, parent, false)
        return bookholder(view)
    }

    fun filterlist(filterlist: ArrayList<Booksmodel>) {
        booklist = filterlist
        notifyDataSetChanged()
    }

    override fun onBindViewHolder(holder: bookholder, position: Int) {
        val book = booklist[position]
        holder.bind(book, itemClickListener, searchText)
    }

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

    inner class bookholder(view: View) : RecyclerView.ViewHolder(view) {
        val bookname: TextView = view.findViewById(R.id.recbooknametxt)
        val bookpublication = view.findViewById<TextView>(R.id.recbookpubtxt)
        val bookdept = view.findViewById<TextView>(R.id.recbookdepttxt)
        val bookimage = view.findViewById<ImageView>(R.id.recbookimg)

        // 修改bind方法,接收searchText参数
        fun bind(book: Booksmodel, clicklistner: OnItemClicklistner, searchText: String) {
            // 对书名应用高亮效果
            bookname.text = getHighlightedText(book.BookName ?: "", searchText)
            bookpublication.text = book.BookPublication
            bookdept.text = book.Department
            Picasso.get().load(book.BookImage).into(bookimage)

            itemView.setOnClickListener {
                clicklistner.onItemclick(book)
            }
        }

        // 核心:生成带高亮的Spannable文本
        private fun getHighlightedText(originalText: String, searchText: String): SpannableString {
            val spannable = SpannableString(originalText)
            if (searchText.isEmpty()) return spannable

            val originalLower = originalText.lowercase(Locale.getDefault())
            val startIndex = originalLower.indexOf(searchText)

            if (startIndex != -1) {
                val endIndex = startIndex + searchText.length
                // 设置高亮颜色(这里用红色,你可以换成自己需要的颜色,比如ContextCompat.getColor(itemView.context, R.color.your_highlight_color))
                val highlightSpan = ForegroundColorSpan(Color.RED)
                spannable.setSpan(
                    highlightSpan,
                    startIndex,
                    endIndex,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
            return spannable
        }
    }

    interface OnItemClicklistner {
        fun onItemclick(books: Booksmodel)
    }
}

第二步:修改Fragment中的filter方法,传递搜索文本

在你的books.kt里,每次搜索文本变化时,除了传递过滤后的列表,还要把当前的搜索文本传给Adapter:

修改后的filter方法:

private fun filter(text: String) {
    val filteredlist = ArrayList<Booksmodel>()
    val lowerCaseText = text.lowercase(Locale.getDefault())
    
    for (item in booklist) {
        if (item.BookName?.lowercase(Locale.getDefault())?.contains(lowerCaseText) == true) {
            filteredlist.add(item)
        }
    }

    if (filteredlist.isEmpty()) {
        Toast.makeText(context, "No Data Found..", Toast.LENGTH_SHORT).show()
    } else {
        bookadapter.filterlist(filteredlist)
    }
    // 新增:把搜索文本传给Adapter
    bookadapter.setSearchText(text)
}

关键逻辑说明

  1. SpannableString:Android提供的富文本工具,可以给文本的指定部分设置样式(颜色、大小、下划线等),这里我们用ForegroundColorSpan来改变匹配文本的颜色。
  2. 大小写不敏感匹配:把原文本和搜索文本都转成小写,避免大小写导致的匹配失败。
  3. 空搜索文本处理:当搜索框为空时,直接返回原文本,保证正常显示。
  4. 实时更新:每次搜索文本变化时,调用setSearchText并触发notifyDataSetChanged,让RecyclerView重新渲染带高亮的条目。

你可以根据自己的需求修改高亮的颜色(比如换成项目里的主题色),如果需要高亮多个匹配的子串,还可以扩展getHighlightedText方法,循环找到所有匹配的位置并设置Span。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:37:38