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

如何通过SearchView过滤自定义Book对象并刷新RecyclerView?

解决方案:用SearchView过滤自定义Book对象列表

第一步:改造RecyclerAdapter,支持过滤

咱们得给你的RecyclerAdapter加上过滤能力,核心思路是维护一份原始的完整书籍列表,每次搜索都从这份原始列表里筛选匹配的Book对象,再更新RecyclerView的显示列表——这样就不会因为多次过滤导致数据丢失啦。

修改后的完整Adapter代码如下:

class BookAdapter(private var bookList: MutableList<Book>) : RecyclerView.Adapter<BookAdapter.BookHolder>(), Filterable {
    // 保存原始的完整书籍列表,避免多次过滤后数据丢失
    private val fullBookList = ArrayList(bookList)

    inner class BookHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

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

    override fun onBindViewHolder(holder: BookHolder, position: Int) {
        val currentBook = bookList[position]
        holder.itemView.isim.text = currentBook.kitapismi
        holder.itemView.aciklama.text = currentBook.kitapaciklama
        holder.itemView.recyler_email.text = currentBook.kullaniciemail
        Picasso.get().load(currentBook.gorselurl).into(holder.itemView.recyler_image)
        
        holder.itemView.setOnClickListener{
            val intent = Intent(holder.itemView.context, BookDetails::class.java)
            intent.putExtra("bookIsmi", currentBook.kitapismi)
            intent.putExtra("bookAciklama", currentBook.kitapaciklama)
            intent.putExtra("bookImage", currentBook.gorselurl)
            intent.putExtra("email", currentBook.kullaniciemail)
            holder.itemView.context.startActivity(intent)
        }
    }

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

    // 实现Filterable接口,核心过滤逻辑在这里
    override fun getFilter(): Filter {
        return object : Filter() {
            // 后台线程执行过滤,避免阻塞UI
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val filteredList = mutableListOf<Book>()
                val query = constraint?.toString()?.lowercase(Locale.getDefault()) ?: ""

                if (query.isEmpty()) {
                    // 搜索框为空时,显示全部书籍
                    filteredList.addAll(fullBookList)
                } else {
                    // 遍历原始列表,匹配书籍名称/描述(你可以自定义匹配字段)
                    for (book in fullBookList) {
                        val bookName = book.kitapismi?.lowercase(Locale.getDefault()) ?: ""
                        val bookDesc = book.kitapaciklama?.lowercase(Locale.getDefault()) ?: ""
                        // 匹配名称或描述,满足任一条件就加入过滤列表
                        if (bookName.contains(query) || bookDesc.contains(query)) {
                            filteredList.add(book)
                        }
                    }
                }

                val results = FilterResults()
                results.values = filteredList
                return results
            }

            // 更新UI线程的列表,并刷新RecyclerView
            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                bookList.clear()
                bookList.addAll(results?.values as MutableList<Book>)
                notifyDataSetChanged()
            }
        }
    }
}

第二步:在BooksActivity中绑定SearchView和过滤逻辑

接下来在你的BooksActivity里,给SearchView设置文本监听,把用户输入的内容传给Adapter的过滤方法:

class BooksActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var bookAdapter: BookAdapter
    // 这里替换成你实际获取书籍列表的逻辑(比如从数据库/网络加载)
    private val bookList = mutableListOf<Book>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_books)

        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        
        // 初始化Adapter
        bookAdapter = BookAdapter(bookList)
        recyclerView.adapter = bookAdapter

        // 绑定SearchView的监听
        val searchView = findViewById<SearchView>(R.id.search_book)
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                // 点击搜索按钮时触发过滤
                bookAdapter.filter.filter(query)
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                // 输入文本实时变化时触发过滤
                bookAdapter.filter.filter(newText)
                return true
            }
        })
    }
}

关键细节说明

  • 自定义匹配字段:在performFiltering方法里,我设置的是匹配书籍名称(kitapismi)和描述(kitapaciklama),你可以根据需求调整,比如只匹配名称,或者加上用户邮箱(kullaniciemail)。
  • 大小写不敏感:把搜索关键词和书籍字段都转成小写,这样搜索时不会区分大小写,提升用户体验。
  • 原始列表的必要性:一定要维护fullBookList,如果直接在显示列表上过滤,多次搜索后会导致数据丢失,因为每次过滤都要基于原始的完整数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:47:28