如何获取Toolbar上SearchView的输入字符串用于列表过滤?
解决步骤
1. 重写Activity/Fragment的onCreateOptionsMenu方法,绑定SearchView输入监听
override fun onCreateOptionsMenu(menu: Menu): Boolean { // 替换为你自己的菜单文件名 menuInflater.inflate(R.menu.your_menu_file, menu) // 找到搜索菜单项 val searchItem = menu.findItem(R.id.menu_search) // 转换为对应类型的SearchView实例 val searchView = searchItem.actionView as androidx.appcompat.widget.SearchView // 设置文本输入监听 searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { // 点击输入法搜索按钮时触发 override fun onQueryTextSubmit(query: String?): Boolean { query?.let { // 调用Adapter的过滤方法,传入用户输入的内容 bookAdapter.filterBooks(it) } return true } // 输入文本实时变化时触发 override fun onQueryTextChange(newText: String?): Boolean { newText?.let { // 需要实时过滤就保留这行,不需要就删掉只在上面的提交方法调用即可 bookAdapter.filterBooks(it) } return true } }) return super.onCreateOptionsMenu(menu) }
注:如果是在Fragment中使用,需要先在
onViewCreated中调用setHasOptionsMenu(true),才能触发onCreateOptionsMenu回调。
2. 改造RecyclerAdapter,新增公开过滤方法
将原有的硬编码过滤逻辑封装成可接收外部输入参数的公开方法:
class BookAdapter(private val originalBookList: List<Book>) : RecyclerView.Adapter<BookViewHolder>() { // 实际渲染用的列表,默认加载全量数据 private var renderList = originalBookList // 公开过滤方法,接收外部传入的搜索关键词 fun filterBooks(userInput: String) { renderList = if (userInput.isEmpty()) { // 输入为空时恢复全量数据 originalBookList } else { // 原有的过滤逻辑,可加ignoreCase = true忽略大小写匹配 originalBookList.filter { it.bookName.contains(userInput, ignoreCase = true) } } // 刷新列表渲染 notifyDataSetChanged() } // 后续的item计数、ViewHolder绑定逻辑都使用renderList即可 override fun getItemCount(): Int = renderList.size }
注意事项
- 导入的SearchView必须和菜单中定义的
app:actionViewClass保持一致,使用androidx.appcompat.widget.SearchView,否则会出现类型转换异常 - 若不需要实时匹配,删除
onQueryTextChange中的过滤调用即可,仅在用户点击搜索按钮时触发过滤
内容的提问来源于stack exchange,提问作者mythredd
相关产品推荐
相关产品推荐

