迁移到AndroidX后,RecyclerView可过滤的performFiltering()无法正常工作

时间:2018-12-07 02:10:09

标签: android kotlin android-recyclerview androidx android-filterable

迁移到AndroidX后,我只是发现我的搜索功能不再起作用。我已经在https://developer.android.com/reference/android/widget/Filterable处检查了官方文档,但没有任何线索。

这是我的RecyclerView适配器ListProdukAdapter.kt,它实现了Filterable:

class ListProdukAdapter(private val context: Context, private val data: List<Produk>, private val act: MainActivity, private val kategori: String) : RecyclerView.Adapter<ListProdukAdapter.SampleViewHolders>(), Filterable {
    private var dataFiltered: List<Produk>? = null
    private val h: Helper
    private val a: HelperAplikasi

    init {
        this.dataFiltered = data
        this.h = act.h
        this.a = act.a
    }

    ...

    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(charSequence: CharSequence): Filter.FilterResults {
                val keyword = charSequence.toString().toLowerCase()
                dataFiltered = if (keyword.isEmpty()) {
                    data
                } else {
                    val filteredList = ArrayList<Produk>()
                    var kategoriBf = ""
                    var kategoriHit = 0
                    val kategoriNum = HashMap<String, Int>()
                    for (res in data) {
                        if (!h.cekVal(res.judul) || h.cekFilter(keyword, res.judul, res.kategorI_LENGKAP, res.keywords) > 0) {
                            filteredList.add(res)
                            if (h.cekVal(res.judul)) {
                                if (kategoriBf != res.kategori && !kategoriBf.isEmpty()) {
                                    kategoriNum[kategoriBf] = kategoriHit
                                    kategoriHit = 0
                                }
                                kategoriHit++
                                kategoriBf = res.kategori
                            }
                        }
                    }
                    kategoriNum[kategoriBf] = kategoriHit
                    Log.e("kategori_num", kategoriNum.toString())
                    Log.e("kategori_num_item_bf", filteredList.size.toString() + "")
                    for (etl in filteredList) {
                        if (!h.cekVal(etl.judul)) {
                            val jumlah = kategoriNum[etl.kategori]
                            if (jumlah == null || jumlah < 1)
                                etl.stok = 0
                            else
                                etl.stok = jumlah
                        }
                    }
                    Log.e("kategori_num_item_af", filteredList.size.toString() + "")
                    filteredList
                }
                val filterResults = Filter.FilterResults()
                filterResults.values = dataFiltered ?: ArrayList<Produk>()
                return filterResults
            }

            override fun publishResults(charSequence: CharSequence, filterResults: Filter.FilterResults) {
                @Suppress("UNCHECKED_CAST")
                dataFiltered = filterResults.values as ArrayList<Produk>
                notifyDataSetChanged()
            }
        }
    }

    ...

}

请注意,在我迁移到AndroidX之前,它就像是一种魅力。我的h.cekFilter()方法只是我用于String的自定义帮助程序,用于检查String是否包含关键字,在那里没有问题。现在,每当在搜索输入中键入任何内容时,我都会崩溃:

kotlin.TypeCastException: null cannot be cast to non-null type kotlin.collections.ArrayList<com.jukat.jualdekat.objects.Produk> /* = java.util.ArrayList<com.jukat.jualdekat.objects.Produk> */
        at com.jukat.jualdekat.adapters.ListProdukAdapter$getFilter$1.publishResults(ListProdukAdapter.kt:239)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5692)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)

当我尝试将(行号239)从dataFiltered = filterResults.values as ArrayList<Produk>更改为dataFiltered = filterResults.values as ArrayList<Produk>?时,即使我键入明显包含在数据中的1个字母,结果也为零。是的,我在所有其他使用类似实现的活动中也遇到了同样的错误。请帮忙。

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

对不起,伙计们。我花了几个小时才弄清楚这个问题,最终我发现了实际上是什么。显然,这个问题根本与AndroidX无关,而是因为我的Helper类中的自定义方法,在我迁移到AndroidX之前,我碰巧将其从Java转换为Kotlin,这使我弄错了。

performFiltering()方法具有可为空的CharSequence参数,因此我的CharSequence?方法中应该像波纹管一样具有h.cekFilter()

fun cekFilter(keyword: CharSequence?, vararg teks: CharSequence?): Int {
    ...
}

另一个问题是Logcat在我的Helper类中未显示任何错误迹象,而是我的performFilter()停止了一半,然后将空filterResults.values传递到publishResults(),然后触发了该错误Logcat中的异常。很奇怪。