【发布时间】:2021-03-09 14:26:19
【问题描述】:
我的布局中有一个 AutoCompleteTextView,它将从 API 获取数据,数据返回两个参数,描述和代码,AutoCompleteText 必须可过滤代码和描述。
为了查看代码和描述,我创建了一个自定义的ArrayAdapter,我试图实现Filterable 方法来设置自定义过滤器,该过滤器将检查代码和描述属性。
问题是,一旦我尝试通过在publishResults 开头投射异常来写入AutoCompleteTextView 我的应用程序崩溃:java.lang.UnsupportedOperationException
那么我怎样才能为我的 ArrayAdapter 实现自定义过滤器?
这是我的适配器代码:
class FornitoriAdapter(context: Context, resource: Int, private val fornitori: List<Fornitori>) :
ArrayAdapter<Fornitori>(context, resource, fornitori), Filterable {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val row: View
val holder: ViewHolder
if (convertView == null) {
val inflater = LayoutInflater.from(context)
row = inflater.inflate(R.layout.list_item, parent, false)
holder = ViewHolder(row)
row.tag = holder
} else {
row = convertView
holder = row.tag as ViewHolder
}
val fornitore: Fornitori = fornitori[position]
holder.descrText.text = fornitore.desc
holder.codeText.text = fornitore.cod
return row
}
override fun getItem(position: Int): Fornitori {
return fornitori[position]
}
override fun getCount(): Int {
return fornitori.size
}
private class ViewHolder constructor(row: View) {
val descrText: TextView = row.findViewById(R.id.description)
val codeText: TextView = row.findViewById(R.id.code)
}
override fun getFilter(): Filter {
return customFilter
}
private val customFilter = object : Filter() {
override fun convertResultToString(resultValue: Any?): CharSequence {
return (resultValue as Fornitori).desc
}
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteredList = mutableListOf<Fornitori>()
if (constraint == null || constraint.isEmpty()) {
filteredList.addAll(fornitori)
} else {
for (item in fornitori) {
if (item.cod.equals(constraint.toString(), ignoreCase = true) || item.desc.toLowerCase(
Locale.ROOT
).startsWith(
constraint.toString().toLowerCase(
Locale.ROOT
)
)
) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, filterResults: FilterResults?) {
clear()
val newValues: List<Fornitori> = filterResults?.values as List<Fornitori>
for (element in newValues) {
add(element)
}
if (filterResults.count > 0) {
notifyDataSetChanged()
} else {
notifyDataSetInvalidated()
}
}
}
}
以及我如何在 Fragment 中管理它:
autocompleteFornitore = view.findViewById(R.id.autocompleteFornitore)
val fornitori: List<Fornitori> = listOf(Fornitori("001", "GAB"), Fornitori("002", "TEST"))
val adapter = FornitoriAdapter(requireContext(), R.layout.list_item, fornitori)
autocompleteFornitore.setAdapter(adapter)
autocompleteFornitore.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
根据需要完整的堆栈跟踪:
2021-03-09 16:05:26.915 31076-31076/it.xxx.xxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: it.xxx.xxx, PID: 31076
java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at java.util.AbstractList.removeRange(AbstractList.java:571)
at java.util.AbstractList.clear(AbstractList.java:234)
at android.widget.ArrayAdapter.clear(ArrayAdapter.java:320)
at it.gabtamagnini.visualstock.adapters.FornitoriAdapter$customFilter$1.publishResults(FornitoriAdapter.kt:88)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6518)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
【问题讨论】:
-
你能告诉我们错误是哪一行抛出的,或者包括完整的堆栈跟踪吗?
-
@HenryTwist 刚刚添加了整个堆栈跟踪
-
@HenryTwist 88 是 clear() 行;
-
为什么要清除数据?这实际上是错误的原因。
-
@KishanMaurya 通过仅设置 addAll 而没有 clear() 我看到相同的数据
标签: android kotlin android-arrayadapter autocompletetextview