Пользовательский ArrayAdapter с фильтром не фильтруется правильно - PullRequest
0 голосов
/ 08 июня 2018

У меня есть следующее ArrayAdapter :

class SearchAdapter(private val activity: Activity, private var species: ArrayList<Specie>) : ArrayAdapter<Specie>(activity, R.layout.specie_item, species) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        return convertView ?: createView(position, parent)
    }

    private fun createView(position: Int, parent: ViewGroup?): View {
        val specie = species[position]

        val view = LayoutInflater.from(context).inflate(R.layout.specie_item, parent, false)
        view.specie_text.text = specie.name

        return view
    }

    override fun getCount() = species.size

    override fun getItem(position: Int) = species[position]

    override fun getFilter() = filter

    private var filter: Filter = object : Filter() {

        override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
            val results = FilterResults()

            val query = if (constraint != null && constraint.isNotEmpty()) autocomplete(constraint.toString())
            else arrayListOf()

            results.values = query
            results.count = query.size

            return results
        }

        private fun autocomplete(input: String): ArrayList<Specie> {
            val results = arrayListOf<Specie>()

            for (specie in species) {
                if (specie.name.toLowerCase().contains(input.toLowerCase())) results.add(specie)
            }

            return results
         }

         override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults) {
            if (results.count > 0) notifyDataSetChanged()
            else notifyDataSetInvalidated()
         }

         override fun convertResultToString(result: Any) = (result as Specie).name
     }
}

Цель этого адаптера - показать некоторые предложения, когда мы вводим что-то в AutoCompleteTextview .Для этого у меня есть фильтр, который ищет названия видов в соответствии с пользовательским вводом.Проблема в том, что этот фильтр работает не так, как я ожидал:

enter image description here Пока все в порядке.Он показывает все названия видов, которые начинаются с agro

enter image description here Но после ввода чего-то большего, он больше не фильтруется.На нем должны отображаться названия видов, начинающиеся с agrostis cas , но все еще отображаются Agrostis azorica .

Мой фильтр плохой?Я пробовал другие способы фильтрации, но получил точно такой же результат.

1 Ответ

0 голосов
/ 08 июня 2018

В настоящее время вам не хватает того, что ваш адаптер ничего не учитывает в вашем фильтре, вы устанавливаете его в зависимости от полного списка видов с вашим счетчиком get, getItemPosition.

Также вам следует позаботиться ообновлять текст, когда представления перерабатываются вашим адаптером, а не устанавливать значение только при создании представлений.

Что-то подобное должно быть лучше:

class SearchAdapter(private val activity: Activity, private var species: ArrayList<Specie>) : ArrayAdapter<Specie>(activity, R.layout.specie_item, species) {

    var filtered = ArrayList<Specie>()

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        return convertView ?: createView(position, parent)
    }

    private fun createView(position: Int, parent: ViewGroup?): View {
        val view = LayoutInflater.from(context).inflate(R.layout.specie_item, parent, false)
        view?.name?.text = filtered[position].name
        return view
    }

    override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup?): View {
        convertView ?: LayoutInflater.from(context).inflate(R.layout.specie_item, parent, false)
        convertView?.name?.text = filtered[position].name
        return super.getDropDownView(position, convertView, parent)
    }

    override fun getCount() = filtered.size

    override fun getItem(position: Int) = filtered[position]

    override fun getFilter() = filter

    private var filter: Filter = object : Filter() {

        override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
            val results = FilterResults()

            val query = if (constraint != null && constraint.isNotEmpty()) autocomplete(constraint.toString())
            else arrayListOf()

            results.values = query
            results.count = query.size

            return results
        }

        private fun autocomplete(input: String): ArrayList<Specie> {
            val results = arrayListOf<Specie>()

            for (specie in species) {
                if (specie.name.toLowerCase().contains(input.toLowerCase())) results.add(specie)
            }

            return results
        }

        override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults) {
            filtered = results.values as ArrayList<Specie>
            notifyDataSetInvalidated()
        }

        override fun convertResultToString(result: Any) = (result as Specie).name
    }
}
...