Why searchview for recyclerview is not working?

211 Views Asked by At

I did my adapter and made a function that would filter my list. But the issue is that it's no showing the results and i don't know why. There 2 lists: one of them is full list and the other one is the filtered list. Here is my adapter:

class SearchAdapter : RecyclerView.Adapter<SearchViewHolder>(), Filterable {

    var fullInstitutionData: ArrayList<InstitutionModel> = ArrayList()
    var institutionData: ArrayList<InstitutionModel> = ArrayList()

    init {
        institutionData = ArrayList()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return SearchViewHolder(inflater, parent)
    }

    override fun getItemCount(): Int = institutionData.size

    override fun onBindViewHolder(holder: SearchViewHolder, position: Int) {
        val dialogData: InstitutionModel = institutionData[position]
        holder.bind(dialogData)
    }

    override fun getFilter(): Filter {
        return customFilter
    }

    fun addDataFromClient(listDataClient: ArrayList<InstitutionModel>) {
        institutionData.addAll(listDataClient)
        fullInstitutionData = ArrayList(listDataClient)
        notifyDataSetChanged()
    }

    private val customFilter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val filteredList = arrayListOf<InstitutionModel>()
            if (constraint == null || constraint.length == 0) {
                filteredList.addAll(institutionData)
            } else {
                val filterPattern = constraint.toString().toLowerCase().trim()
                for (item in fullInstitutionData) {
                    if (item.name.toLowerCase().contains(filterPattern) || item.name?.toLowerCase()!!
                                    .contains(filterPattern)) {
                        filteredList.add(item)
                    }
                }
            }
            val results = FilterResults()
            results.values = filteredList
            return results
        }

        override fun publishResults(constraint: CharSequence?, filterResults: FilterResults?) {
            institutionData.clear()
            institutionData.addAll(filterResults?.values as MutableList<InstitutionModel>)

        }

    }

}

And this is my search function that i did the setOnQueryListener in the my fragment:

 fun searchInstitution() {
        searchViewInstitutions.apply {
            setOnQueryTextListener(object : SearchView.OnQueryTextListener {
                override fun onQueryTextSubmit(query: String): Boolean {
                    return false
                }

                override fun onQueryTextChange(newText: String?): Boolean {
                    searchAdapter.filter.filter(newText)
                    return false
                }

            })

        }
    }

This is the code when i call the recyclerview on onActivityCreated:

 val llm = LinearLayoutManager(context)
    llm.orientation = LinearLayoutManager.VERTICAL
    rvSearch.layoutManager = llm
    rvSearch.adapter = SearchAdapter()

    searchAdapter.addDataFromClient(data)
    searchInstitution()
1

There are 1 best solutions below

5
Zain On

There are two fixes needed:

  • notifyDataSetChanged() when you publishResults()

     override fun publishResults(constraint: CharSequence?, filterResults: FilterResults?) {
         institutionData.clear()
         institutionData.addAll(filterResults?.values as MutableList<InstitutionModel>)
         notifyDataSetChanged() // <<< Change Here
     }
    
  • Add the full list when there is no match instead of the filtered one

     override fun performFiltering(constraint: CharSequence?): FilterResults {
         val filteredList = arrayListOf<InstitutionModel>()
         if (constraint == null || constraint.length == 0) {
             filteredList.addAll(fullInstitutionData) // <<< Change Here