我正在尝试为RecyclerView
实现一个过滤器。我使用数据绑定(bind),并且我的适配器是ListAdapter
子类,如下所示
class BookAdapter(private val clickListener: ClickHandler) :
ListAdapter<Book, BookAdapter.ViewHolder>(BooksDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position)!!, clickListener)
}
class ViewHolder private constructor(val binding: BookItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(
item: Book,
clickListener: ClickHandler
) {
binding.book = item
binding.clickListener = clickListener
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = BookItemBinding.inflate(inflater, parent, false)
return ViewHolder(binding)
}
}
}
}
class BooksDiffCallback : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem == newItem
}
}
class ClickHandler(val clickListener: (id: String) -> Unit) {
fun onClick(item: Book) = clickListener(item.id)
}
根据文档,要添加过滤功能,我需要在适配器中实现
Filterable
并定义getFilter()
方法。这就是我坚持的地方:在getFilter()
的情况下,我根本不知道如何实现ListAdapter
。任何帮助将不胜感激。 最佳答案
我遇到了类似的问题,并尝试使用类似于上述Maor Hadad描述的方法来解决它。它有时起作用,并且在
方法。所以,我这样解决了。
首先创建一个变量private var unfilteredlist = listOf<BaseDataItem>()
和一个方法
fun modifyList(list : List<BaseDataItem>) {
unfilteredList = list
submitList(list)
}
fun filter(query: CharSequence?) {
val list = mutableListOf<BaseDataItem>()
// perform the data filtering
if(!query.isNullOrEmpty()) {
list.addAll(unfilteredList.filter {
it.*field1*.toLowerCase(Locale.getDefault()).contains(query.toString().toLowerCase(Locale.getDefault())) ||
it.*field2*.toLowerCase(Locale.getDefault()).contains(query.toString().toLowerCase(Locale.getDefault())) })
} else {
list.addAll(unfilteredList)
}
submitList(list)
}
在
BookAdapter
类中。 *field1*
和*field2*
(您可以添加更多字段)是您要搜索查询匹配的字段。然后,无论您在原始代码中调用adapter.submitList(List<BaseDataItem>)
的何处,都将其替换为自定义方法adapter.modifyList(List<BaseDataItem>)
。然后像下面这样写
searchView.setOnQueryTextListener
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
(binding.recycler.adapter as ItemAdapter).filter(newText)
return true
}
})
不要忘记删除
Filterable
接口(interface)及其方法,您不再需要它们