实现RecyclerView过滤器时触发IndexOutOfBoundsException异常求解决方案
问题根因
最核心的错误是getItemCount()方法返回的是原始未过滤列表item_list的长度,而RecyclerView渲染、绑定item时依赖的是过滤后的filteredList。当过滤操作执行后,filteredList的长度小于原始列表长度时,RecyclerView会按照原始列表的长度请求对应position的item,自然会出现索引超出filteredList范围的IndexOutOfBoundsException异常,和你是否调用notifyDataSetChanged()无关。
修复步骤
- 第一步:修正
getItemCount返回值
将原有的返回原始列表长度的逻辑替换为返回过滤后列表的长度,同时处理空安全:
override fun getItemCount(): Int = filteredList?.size ?: 0
- 第二步:修复列表引用共用问题
你当前在无过滤关键词时直接将filteredList = item_list,两者指向同一个内存地址,后续如果修改filteredList会直接污染原始列表,建议无过滤时做浅拷贝:
override fun getFilter(): Filter? { return object : Filter() { override fun performFiltering(constraint: CharSequence): FilterResults { val charString = constraint.toString() val tempFilteredList = if (charString.isEmpty()) { // 无过滤条件时拷贝原始列表,避免共用引用 item_list.toMutableList() } else { val filteringList = ArrayList<items_list>() for (name in item_list) { if (name.item_name.lowercase().contains(charString.lowercase())) { filteringList.add(name) } } filteringList } val filterResults = FilterResults() filterResults.values = tempFilteredList return filterResults } override fun publishResults(constraint: CharSequence, results: FilterResults) { // 增加安全类型转换,避免强转崩溃 filteredList = results.values as? MutableList<items_list> ?: item_list.toMutableList() notifyDataSetChanged() } } }
- 可选优化:消除冗余空判断
可以将filteredList改为非空类型,避免后续频繁判空:
// 初始化时直接拷贝原始列表,去掉可空标识? var filteredList: MutableList<items_list> = item_list.toMutableList() // 对应getItemCount可以简化为 override fun getItemCount(): Int = filteredList.size
修复以上问题后,索引越界异常就会消失。
内容的提问来源于stack exchange,提问作者jmmjm
相关产品推荐
相关产品推荐

