适配器数据mutableList修改后崩溃

时间:2019-07-09 10:16:26

标签: android arrays kotlin

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

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

这是我的完整适配器代码

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中的一个(只有一个)从未启动,其他一切都很好

(对不起,我不是英语)

1 个答案:

答案 0 :(得分:0)

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

var filterList : mutableListOf<FishModel>()

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

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

    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

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