Ale*_*lex 13 filtering listadapter kotlin android-recyclerview
我正在尝试为我的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)
}
Run Code Online (Sandbox Code Playgroud)
根据文档,要添加过滤功能,我需要Filterable在我的适配器中实现并定义getFilter()方法。这就是我坚持的地方:我根本不知道如何getFilter()在ListAdapter. 任何帮助将不胜感激。
小智 15
我遇到了类似的问题,并尝试使用类似于上面Maor Hadad描述的方法来解决它。它在某些时候起作用,并在
Filter.publishResult()
方法。所以,我是这样解决的。首先创建一个变量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)
}
Run Code Online (Sandbox Code Playgroud)
在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
}
})
Run Code Online (Sandbox Code Playgroud)
不要忘记删除Filterable接口及其方法,您不再需要它们了
我没有找到获取该列表的方法,因此我保存了对我的列表的引用。代码示例:
ListAdapter:实现可过滤:
class ItemAdapter(private val clickListener: ItemListener) :
ListAdapter<ItemAdapter.BaseDataItem, RecyclerView.ViewHolder>(ItemDiffCallBack()), Filterable {
Run Code Online (Sandbox Code Playgroud)
添加变量供参考:
var mListRef: List<BaseDataItem>? = null
var mFilteredList: List<BaseDataItem>? = null
Run Code Online (Sandbox Code Playgroud)
在第一次提交列表之前,请保存其参考文献
withContext(Dispatchers.Main) {
if (mListRef == null) {
mListRef = items
}
submitList(items)
}
Run Code Online (Sandbox Code Playgroud)
过滤器:
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在片段内搜索,请添加以下内容:
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
}
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2961 次 |
| 最近记录: |