修改后适配器数据mutableList崩溃 [英] Adapter data mutableList crash when modified

查看:130
本文介绍了修改后适配器数据mutableList崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的Filter对象中的RecyclerView创建SearchView过滤器,在有趣的"publishResults"中,我的应用程序崩溃,因为我试图修改mutableListOf,但修改了data.clear()和data.addAll ()导致错误

I'm making a SearchView Filter for a RecyclerView, in my Filter object, in the fun 'publishResults', my app crash because i'm trying to modify a mutableListOf, but the data.clear() and data.addAll() cause an error

对列表的每次修改似乎都会导致应用崩溃,尽管我尝试修改了所有其他列表,但我从未见过此错误.我认为问题来自于recyclerView使用的事实,但我不知道为什么,我在互联网上找不到任何东西,而使用科特林语言则更少. 尝试将results?.values强制转换为Collection时,似乎也有一个大问题.

Every modification to the list seems to make the app crash, I've never seen this error despite all other list I've tried to modify. I think the problem come from the fact that it's used by the recyclerView but I have no clue why, I've find nothing on internet and even less with kotlin language. Also it seems like there is a big problem when trying to cast the results?.values to a Collection.

这是我的完整适配器代码

here is my full Adapter code

class SmallCatchAdapter(val clickListener: FishModelListener) : RecyclerView.Adapter<SmallCatchAdapter.ViewHolder>(), Filterable {

var data = mutableListOf<FishModel>()
    set(value) {
        field = value
        notifyDataSetChanged()
    }

var dataFull = listOf<FishModel>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder.from(parent)
}

override fun getItemCount() = data.size

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = data[position]
    holder.bind(item, clickListener)
}

class ViewHolder private constructor(val binding: ItemListSmallCatchBinding): RecyclerView.ViewHolder(binding.root) {
    fun bind(item : FishModel, clickListener: FishModelListener) {
        binding.fishModel = item
        binding.clickListener = clickListener
        binding.executePendingBindings()
    }

    companion object{
        fun from(parent: ViewGroup): ViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val binding = ItemListSmallCatchBinding.inflate(layoutInflater, parent, false)

            return ViewHolder(binding)
        }
    }

}

override fun getFilter(): Filter {
    return fishListFilter
}

private val fishListFilter = object : Filter() {
    override fun performFiltering(constraint: CharSequence?): FilterResults {
        val dataFiltered = mutableListOf<FishModel>()
        if (constraint == null || constraint.isEmpty()) {
            dataFiltered.addAll(dataFull)
        } else {
            val filterPattern: String = constraint.toString().toLowerCase().trim()
            for (item in dataFull) {
                if(item.name.toLowerCase().contains(filterPattern)) {
                    dataFiltered.add(item)
                }
            }
        }
        val results = FilterResults()
        results.values = dataFiltered
        return results
    }

    override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
        data.clear()
        data.addAll(results?.values as MutableList<FishModel>)
        notifyDataSetChanged()
    }
}

}

class FishModelListener(val clickListener: (fishModelId: Int) -> Unit) {
    fun onClick(fishModel: FishModel) = clickListener(fishModel.speciesID)

}

崩溃的地方

override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            data.clear()
            data.addAll(results?.values as Collection<FishModel>)
            notifyDataSetChanged()
        }

错误:

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)

在我实现此功能之前,一切工作都很好,现在我还注意到此错误以某种方式使我的Room Query混乱了,我的coroutineScope(仅一个)从未启动,其他一切都还可以

Everything worked well before i implement this functionality, now I've also noticed that this bug has somehow messed with my Room Query, one (and only one) of my coroutineScope is never launched, everythings else is ok

(对不起,我不是英语)

(Sorry for the mistakes, i'm not english)

推荐答案

您应该创建另一个列表变量并使用它,而不是在onBindViewHolder中使用数据

Instead of using data inside onBindViewHolder you should create another list variable and use it

var filterList : mutableListOf<FishModel>()

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = filterList[position]
    holder.bind(item, clickListener)
}

对于过滤器,我正在显示一些参考,请按照以下类似方式进行操作:

For the filter I am showing some references, follow a similar way as below:

    private val customFilter: Filter = object : Filter() {
        override fun performFiltering(constraint: CharSequence): FilterResults {
            filterList =
                if (constraint.isEmpty()) {
                    items.toMutableList()
                } else {
                    items.filter {
                        it.name.contains(constraint, true) ||
                                it.name == constraint ||
                                it.price.toString() == constraint
                    }
                        .toMutableList()
                }

            if (sortByPV) {
                filterList.sortByDescending { it.pointValue }
            }

            return FilterResults().apply {
                values = filterList
                count = filterList.size
            }
        }

        override fun publishResults(constraint: CharSequence, results: FilterResults) {
            notifyDataSetChanged()
        }
    }

    override fun getFilter(): Filter = customFilter
    override fun getItemCount() = filterList.size

在这里,您可能需要相应地更新项目单击侦听器的代码.

Here, you may need to update your code accordingly for item click listener.

这篇关于修改后适配器数据mutableList崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆