Почему searchview для recyclerview не работает?

avatar
Gabriel
1 июля 2021 в 19:46
155
1
0

Я сделал свой адаптер и сделал функцию, которая будет фильтровать мой список. Но проблема в том, что он не показывает результаты, и я не знаю, почему. Там 2 списка: один полный список, а другой отфильтрованный список. Вот мой адаптер:

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>)

        }

    }

}

И это моя функция поиска, которую я сделал setOnQueryListener в моем фрагменте:

 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
                }

            })

        }
    }

Это код, когда я вызываю recyclerview для onActivityCreated:

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

    searchAdapter.addDataFromClient(data)
    searchInstitution()
Источник

Ответы (1)

avatar
Zain
1 июля 2021 в 19:57
0

Необходимо два исправления:

  • notifyDataSetChanged() когда вы publishResults()

     override fun publishResults(constraint: CharSequence?  filterResults: FilterResults?) {
         institutionData.clear()
         institutionData.addAll(filterResults?.values as MutableList<InstitutionModel>)
         notifyDataSetChanged() // <<< Change Here
     }
    
  • Добавить полный список при отсутствии совпадений вместо отфильтрованного

     override fun performFiltering(constraint: CharSequence?): FilterResults {
         val filteredList = arrayListOf<InstitutionModel>()
         if (constraint == null || constraint.length == 0) {
             filteredList.addAll(fullInstitutionData) // <<< Change Here
    
Gabriel
1 июля 2021 в 20:10
0

Спасибо за ответ, но все еще не работает. Я добавил к своему описанию скриншот эмулятора.

Zain
1 июля 2021 в 20:13
0

@Gabriel, вы можете использовать institutionData = filterResults?.values as MutableList<InstitutionModel> вместо clear() и addAll() в publishResults()

Gabriel
1 июля 2021 в 20:15
0

Я получил эту ошибку: Type mismatch: inferred type is MutableList<InstitutionModel> but kotlin.collections.ArrayList<InstitutionModel> /* = java.util.ArrayList<InstitutionModel> */ was expected. Я перешел на ArrayList, но все еще не работает.

Zain
1 июля 2021 в 20:27
0

Попробуйте это institutionData = filterResults?.values as ArrayList<InstitutionModel>

Gabriel
1 июля 2021 в 20:29
0

Я сделал это и запустил проект, но он не изменился