Skip to content

Instantly share code, notes, and snippets.

@UbadahJ
Last active May 5, 2024 02:25
Show Gist options
  • Save UbadahJ/99818433d0ea72f728d66417a7d52afc to your computer and use it in GitHub Desktop.
Save UbadahJ/99818433d0ea72f728d66417a7d52afc to your computer and use it in GitHub Desktop.
A filterable ListAdapter for RecyclerView

Filterable List Adapter

These are the steps to use the adapter.

  1. Replace the adapter extending ListAdapter with FilterableListAdapter.
  2. Implement the method onFilter that provides a List and the string the was passed to the filter method
  3. Update the list according the constraint

Usage

val filterAdapter = null // Your adapter instance here
filterAdapter.filter.filter(/*Pass your string here*/)
abstract class FilterableListAdapter<T, VH : RecyclerView.ViewHolder>(
diffCallback: DiffUtil.ItemCallback<T>
) : ListAdapter<T, VH>(diffCallback), Filterable {
private var originalList: List<T> = currentList.toList()
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
return FilterResults().apply {
values = if (constraint.isNullOrEmpty())
originalList
else
onFilter(originalList, constraint.toString())
}
}
@Suppress("UNCHECKED_CAST")
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
submitList(results?.values as? List<T>, true)
}
}
}
override fun submitList(list: List<T>?) {
submitList(list, false)
}
abstract fun onFilter(list: List<T>, constraint: String): List<T>
/**
* This function is responsible for maintaining the
* actual contents for the list for filtering
* The submitList for parent class delegates false
* so that a new contents can be set
* While a filter pass true which make sure original list
* is maintained
*
* @param filtered True if the list was updated using filter interface
* */
private fun submitList(list: List<T>?, filtered: Boolean) {
if (!filtered)
originalList = list ?: listOf()
super.submitList(list)
}
}
@ArcherEmiya05
Copy link

Hello, how can we use this with header itemview? It seems ListAdapter by default does not support it and after trying it the list behaves weird as it starts at the bottom. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment