/
DynamicSearchAdapter.kt
61 lines (50 loc) · 2.3 KB
/
DynamicSearchAdapter.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package stacktex.mobin.search.adapter
import android.widget.Filter
import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView
abstract class DynamicSearchAdapter<T : DynamicSearchAdapter.Searchable>(private val searchableList: MutableList<T>) :
RecyclerView.Adapter<ViewHolder>(), Filterable {
// Single not-to-be-modified copy of original data in the list.
private val originalList = ArrayList(searchableList)
// a method-body to invoke when search returns nothing. It can be null.
private var onNothingFound: (() -> Unit)? = null
/**
* Searches a specific item in the list and updates adapter.
* if the search returns empty then onNothingFound callback is invoked if provided which can be used to update UI
* @param s the search query or text. It can be null.
* @param onNothingFound a method-body to invoke when search returns nothing. It can be null.
*/
fun search(s: String?, onNothingFound: (() -> Unit)?) {
this.onNothingFound = onNothingFound
filter.filter(s)
}
override fun getFilter(): Filter {
return object : Filter() {
private val filterResults = FilterResults()
override fun performFiltering(constraint: CharSequence?): FilterResults {
searchableList.clear()
if (constraint.isNullOrBlank()) {
searchableList.addAll(originalList)
} else {
val searchResults = originalList.filter { it.getSearchCriteria().contains(constraint) }
searchableList.addAll(searchResults)
}
return filterResults.also {
it.values = searchableList
}
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
// no need to use "results" filtered list provided by this method.
if (searchableList.isNullOrEmpty())
onNothingFound?.invoke()
notifyDataSetChanged()
}
}
}
interface Searchable {
/** This method will allow to specify a search string to compare against
your search this can be anything depending on your use case.
*/
fun getSearchCriteria(): String
}
}