我正在尝试为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)及其方法,您不再需要它们

10-08 17:38