android - 带有过滤器的自定义 ArrayAdapter 未正确过滤
问题描述
我有以下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中键入内容时显示一些建议。为此,我有一个过滤器,可以根据用户输入搜索物种名称。问题是这个过滤器没有像我预期的那样工作:
但是在输入更多内容后,它不再过滤。它应该显示以agrostis cas开头的物种名称,但它仍然显示Agrostis azorica。
我的过滤器坏了吗?我尝试了其他一些过滤方法,但得到了完全相同的结果。
解决方案
您目前缺少的是您的适配器没有考虑有关您的过滤器的任何内容,您将其设置为依赖于您的获取计数 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
}
}
推荐阅读
- javascript - 前置摄像头无法自动对焦或手动对焦
- angular - 订阅多个 observable 并在条件匹配后仅获得一个
- unit-testing - 我有 symfony/phpunit-bridge 的问题
- asp.net - Sitefinity 自定义小部件错误 - 未找到视图“Write.Default”或其主视图,或者没有视图引擎支持搜索的位置
- android - 当我构建 apk 时,代码中的更改不会生效
- javascript - 将粘贴文本上的字符计数到输入字段中的正确方法是什么?
- c# - 如何让物体粘在手上而不是掉落
- r - 如何在 R 中合并两个数据集中的特定行?
- hl7-fhir - HapiFhir toListOfResourcesOfType() 方法有什么作用?
- django - Django:列出数据库中的项目未显示在 html 模板上