android - 带过滤器的自定义 ArrayAdapter 未正确过滤

标签 android filter kotlin android-arrayadapter comparator

我有以下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。 p>

我的过滤器坏了吗?我尝试了一些其他方法来过滤,但得到了完全相同的结果。

最佳答案

您当前缺少的是您的适配器没有考虑有关您的过滤器的任何信息,您将其设置为取决于完整的物种列表以及您的获取计数 getItemPosition。

此外,当适配器回收 View 时,您应该注意更新文本,而不是仅在创建 View 时设置值。

类似的东西应该更好:

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

关于android - 带过滤器的自定义 ArrayAdapter 未正确过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50763436/

相关文章:

android - 如何构建模块化应用程序

grails - 在Grails中强制使用https

android-studio - 如何在 Android Studio 中将 != 转换为 ≠ 和 -> 转换为 →?

android - 计算堆栈大小时,Android,gradle,Proguard错误:

android - Kotlin (Android) - 为非可变函数传播一个数组/列表

android - 如何在不扩展 Activity 的类中显示 Toast 消息

android - 如何使用 Android adb logcat 按标签名称排除某些消息?

ios - 过滤包含对象列表的表 - Swift

java - Kotlin 无法获取所需的类型干扰 Array<Uri>!找到数组<Uri?>

kotlin - 错误 : Exception in thread "main" java. lang.NumberFormatException:对于输入字符串: "kotlin.Unit"