Android 带有筛选器的自定义ArrayAdapter未正确筛选

Android 带有筛选器的自定义ArrayAdapter未正确筛选,android,filter,kotlin,android-arrayadapter,comparator,Android,Filter,Kotlin,Android Arrayadapter,Comparator,我有以下阵列适配器: 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:

我有以下阵列适配器

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
     }
}
class SearchAdapter(私有val活动:活动,私有var种类:ArrayList):ArrayAdapter(活动,R.layout.specie_项目,种类){
覆盖视图(位置:Int,转换视图:View?,父视图:ViewGroup?):视图{
返回convertView?:createView(位置,父级)
}
私有视图(位置:Int,父视图组?):视图{
瓦尔物种=物种[位置]
val view=LayoutInflater.from(上下文)。充气(R.layout.specie_项,父项,false)
view.specie_text.text=specie.name
返回视图
}
覆盖fun getCount()=物种大小
覆盖趣味getItem(位置:Int)=种类[位置]
重写getFilter()=筛选器
私有变量过滤器:过滤器=对象:过滤器(){
重写性能筛选(约束:CharSequence?):Filter.FilterResults{
val结果=FilterResults()
val query=if(constraint!=null&&constraint.isNotEmpty())自动完成(constraint.toString())
else arrayListOf()
results.values=查询
results.count=query.size
返回结果
}
私有乐趣自动完成(输入:字符串):ArrayList{
val results=arrayListOf()
用于(物种){
if(specie.name.toLowerCase().contains(input.toLowerCase())results.add(specie)
}
返回结果
}
重写fun publishResults(约束:CharSequence?,结果:Filter.FilterResults){
如果(results.count>0)notifyDataSetChanged()
else NOTIFYDATESETINVALIDATED()
}
重写fun convertResultToString(结果:任意)=(结果为物种)。名称
}
}
此适配器的用途是在自动完成文本视图中键入内容时显示一些建议。为此,我有一个过滤器,可以根据用户输入搜索物种名称。问题是此筛选器未按预期工作:

在这里之前,一切都很好。它显示了所有以农业开始的物种名称

但在输入更多内容后,它不再进行过滤。它应该显示以agrostis cas开头的物种名称,但仍然显示agrostis azorica


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

您当前缺少的是适配器没有考虑过滤器的任何内容,您可以将其设置为依赖于完整的物种列表以及get count、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
    }
}
class SearchAdapter(私有val活动:活动,私有var种类:ArrayList):ArrayAdapter(活动,R.layout.specie_项目,种类){
var filtered=ArrayList()
覆盖视图(位置:Int,转换视图:View?,父视图:ViewGroup?):视图{
返回convertView?:createView(位置,父级)
}
私有视图(位置:Int,父视图组?):视图{
val view=LayoutInflater.from(上下文)。充气(R.layout.specie_项,父项,false)
查看?.name?.text=已筛选的[位置].name
返回视图
}
覆盖getDropDownView(位置:Int,convertView:View?,父级:ViewGroup?):视图{
convertView?:LayoutFlater.from(上下文)。充气(R.layout.specie_项,父项,false)
convertView?.name?.text=已筛选的[position].name
return super.getDropDownView(位置、转换视图、父级)
}
重写fun getCount()=筛选的.size
覆盖项(位置:Int)=已过滤[位置]
重写getFilter()=筛选器
私有变量过滤器:过滤器=对象:过滤器(){
重写性能筛选(约束:CharSequence?):Filter.FilterResults{
val结果=FilterResults()
val query=if(constraint!=null&&constraint.isNotEmpty())自动完成(constraint.toString())
else arrayListOf()
results.values=查询
results.count=query.size
返回结果
}
私有乐趣自动完成(输入:字符串):ArrayList{
val results=arrayListOf()
用于(物种){
if(specie.name.toLowerCase().contains(input.toLowerCase())results.add(specie)
}
返回结果
}
重写fun publishResults(约束:CharSequence?,结果:Filter.FilterResults){
筛选=结果。值作为ArrayList
notifyDataSetionValidated()
}
重写fun convertResultToString(结果:任意)=(结果为物种)。名称
}
}

您的答案似乎有效!唯一的问题是,这些建议一直隐藏着,并显示每一种我键入的字母。就像他们每次都在重新创造一样。有没有办法避免这个问题?它的显示和隐藏是因为我只放了NotifyDataSetValidated,我必须承认我有点太懒了,无法解决这个问题,我想你应该先了解你的过滤问题,刷新当然可以解决,我明白了。我将尝试调查这种展示和隐藏的行为。非常感谢。