You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin获取RecyclerView选中复选框值报空指针异常

Android复选框联动崩溃修复与实现方案

崩溃根因

点击按钮触发空指针的核心原因有两个:

  • Adapter伴生对象中定义的selectedCheckboxes仅声明了可空类型,从未做初始化,使用!!强制调用clear()方法时直接触发空指针
  • 原有在onBindViewHolder中维护选中项列表的写法本身存在设计缺陷:RecyclerView的复用机制会导致onBindViewHolder重复触发,会出现选中项重复添加、误删的问题,即使初始化了变量也会出现数据错乱。

另外isAllItemsSameStatus方法中存在分类筛选逻辑错误:子列表筛选条件写为it.category == it.category(恒为真),会导致课程分类联动状态判断错误。

修复步骤

1. 替换按钮点击逻辑,移除冗余选中列表维护

不需要额外维护全局选中列表,直接从Adapter持有的数据源中筛选选中项即可,从根源避免空指针。
将Activity中按钮点击代码替换为:

findViewById<Button>(R.id.showTextBtn).setOnClickListener {
    val selectedSubjects = adapter.productList
        .filter { it.rowType == RowType.SubjectRow && it.isChecked }
        .map { it.subjectName }
    val checkboxesValue = selectedSubjects.joinToString(separator = ";")
    findViewById<TextView>(R.id.ShowTextView).text = checkboxesValue
}

2. 清理Adapter中冗余代码

  • 删除Adapter伴生对象中的selectedCheckboxes声明
  • 删除onBindViewHolder末尾在绑定阶段增删选中项、弹出Toast的冗余代码块
  • 修复isAllItemsSameStatus方法中的筛选逻辑错误,将子列表筛选代码改为:
val subList = productList.filter { it.category == cat && it.rowType == RowType.SubjectRow }

使用string-array资源替换硬编码数据

1. 新建数组资源文件

在res/values/路径下新建arrays.xml,写入分类与学科配置:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="all_courses">All Courses</string>
    <!-- 各分类对应学科列表 -->
    <string-array name="Science">
        <item>Physics</item>
        <item>Math</item>
        <item>Chemistry</item>
    </string-array>
    <string-array name="Arts">
        <item>Economics</item>
        <item>History</item>
        <item>Political Science</item>
    </string-array>
    <string-array name="Commerce">
        <item>Accountancy</item>
        <item>Business Studies</item>
        <item>Physical Education</item>
    </string-array>
    <!-- 分类名称列表 -->
    <string-array name="course_categories">
        <item>Science</item>
        <item>Arts</item>
        <item>Commerce</item>
    </string-array>
</resources>

2. 动态生成列表数据

替换Activity中原先硬编码的列表初始化逻辑,从资源文件读取数据生成列表:

val list = mutableListOf<RowModel>()
// 添加顶部全选项
list.add(RowModel(RowType.TopHeader, "", "", false))
// 读取分类列表
val categories = resources.getStringArray(R.array.course_categories)
categories.forEach { category ->
    // 添加课程分类项
    list.add(RowModel(RowType.Course, "", category, false))
    // 读取分类下对应学科
    val subjectResId = resources.getIdentifier(category, "array", packageName)
    val subjects = resources.getStringArray(subjectResId)
    subjects.forEach { subject ->
        list.add(RowModel(RowType.SubjectRow, subject, category, false))
    }
}

优化建议

  • 统一RowModel中isChecked的默认值,避免初始化状态与预期不符
  • 不要在Adapter伴生对象中存储页面相关的状态数据,容易引发内存泄漏与状态不同步问题,所有状态以数据源为准
  • 列表项更新时尽量使用notifyItemChanged的payload重载,避免全量绑定导致的监听重复触发问题

内容的提问来源于stack exchange,提问作者CHETAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:18:21