我正在尝试为我的RecyclerView
实现过滤器。我使用数据绑定,并且我的适配器是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
。任何帮助将不胜感激。
我没有找到获取列表的方法,所以我保存了对列表的引用。代码示例:
ListAdapter:实施可过滤:
class ItemAdapter(private val clickListener: ItemListener) :
ListAdapter<ItemAdapter.BaseDataItem, RecyclerView.ViewHolder>(ItemDiffCallBack()), Filterable {
添加变量以供参考:
var mListRef: List<BaseDataItem>? = null
var mFilteredList: List<BaseDataItem>? = null
在您第一次提交列表之前,请先保存其引用
withContext(Dispatchers.Main) {
if (mListRef == null) {
mListRef = items
}
submitList(items)
}
过滤器:
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(charSequence: CharSequence): FilterResults {
val charString = charSequence.toString()
if (charString.isEmpty()) {
mFilteredList = mListRef
} else {
mListRef?.let {
val filteredList = arrayListOf<BaseDataItem>()
for (baseDataItem in mListRef!!) {
if (baseDataItem is BaseDataItem.DataItemWrapper) {
if (charString.toLowerCase(Locale.ENGLISH) in baseDataItem.dataItem.Name.toLowerCase(
Locale.ENGLISH
)
) {
filteredList.add(baseDataItem)
}
}
}
mFilteredList = filteredList
}
}
val filterResults = FilterResults()
filterResults.values = mFilteredList
return filterResults
}
override fun publishResults(
charSequence: CharSequence,
filterResults: FilterResults
) {
mFilteredList = filterResults.values as ArrayList<BaseDataItem>
submitList(mFilteredList)
}
}
}
如果您在片段中搜索,请添加以下内容:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
val mSearchMenuItem = menu.findItem(R.id.search)
val searchView = mSearchMenuItem.actionView as SearchView
search(searchView)
super.onCreateOptionsMenu(menu, inflater)
}
private fun search(searchView: SearchView) {
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.filter(newText)
return true
}
})
}