我浏览了所有互联网,但没有找到关于如何使用kotlin和searchview在recyclerview中实现过滤器的明确答案。除了我看不到recyclerview的任何区别外,一切都在国际象棋中发生。
任何帮助将不胜感激。这是代码:
class RecetaFragment : Fragment(), SearchView.OnQueryTextListener {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Get a reference to the binding object and inflate the fragment views.
val binding: FragmentRecetaBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_receta_tracker, container, false)
val application = requireNotNull(this.activity).application
(...)
binding.recetaViewModel = recetaViewModel
//invocamos al adaptador creado
val adapter = RecetaAdapter(RecetaListener {
...
},
LongRecetaListener {
...
}
)
binding.recetaList.adapter = adapter
recetaViewModel.recetas.observe(viewLifecycleOwner, Observer {
it?.let{
adapter.submitList(it)
}
})
binding.setLifecycleOwner(this)
...
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
//super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.overflow_search, menu)
val searchItem = menu?.findItem(R.id.action_search)
val searchView = searchItem?.actionView as SearchView
searchView.setOnQueryTextListener(this)
}
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
val adapter = RecetaAdapter(RecetaListener {},
LongRecetaListener {}
)
adapter.filter?.filter(newText)
return false
}
}
我的适配器类:
class RecetaAdapter(val clickListener: RecetaListener, val longClickListener: LongRecetaListener) :
ListAdapter<Receta,RecetaAdapter.ViewHolder>(RecetaDiffCallback()), Filterable{
private val exampleList: MutableList<Receta>? = null
private val exampleListFull: MutableList<Receta>? = null
override fun getFilter(): Filter? {
return exampleFilter
}
private val exampleFilter: Filter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults? {
val filteredList: MutableList<Receta> = ArrayList()
if (constraint == null || constraint.isEmpty()) {
filteredList.addAll(exampleListFull!!)
} else {
val filterPattern =
constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in exampleListFull!!) {
if (item.campoTexto.toLowerCase().contains(filterPattern)) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(
constraint: CharSequence?,
results: FilterResults
) {
exampleList?.clear()
exampleList?.addAll(results.values as MutableList<Receta>)
notifyDataSetChanged()
}
}
//indica como se debe crear el viewholder
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent)
}
//indica al recyclerview que debe mostrar
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position)!!, clickListener, longClickListener)
}
class ViewHolder private constructor(val binding: ListItemRecetaBinding): RecyclerView.ViewHolder(binding.root){
fun bind(item: Receta, clickListener: RecetaListener, longClickListener: LongRecetaListener) {
binding.sleep = item
binding.clickListener = clickListener
binding.longclickListener = longClickListener
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ListItemRecetaBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding)
}
}
}
}
class RecetaDiffCallback: DiffUtil.ItemCallback<Receta>() {
override fun areItemsTheSame
(oldItem: Receta, newItem: Receta): Boolean {
return oldItem.nightId == newItem.nightId
}
override fun areContentsTheSame(oldItem: Receta, newItem: Receta): Boolean {
return oldItem == newItem
}
}