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

Kotlin中RecyclerView适配器调用setImageResource报空指针异常

问题现象

调用setImageResource方法时触发致命空指针异常,异常日志如下:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference

异常出现在Kotlin开发的桌游管理应用的自定义RecyclerView适配器BgAdapter中,触发位置为onBindViewHolder生命周期内,根据桌游收藏状态切换收藏图标资源的代码段:

if (currentBg.faved) {
    holder.bgFavIcon.setImageResource(R.drawable.ic_check)
} else {
    holder.bgFavIcon.setImageResource(R.drawable.ic_add_light)
}
根因分析

findViewById在匹配不到对应id的控件时会返回null,你的代码中bgFavIcon被声明为非空ImageView类型,但实际运行时获取到的是null值,调用setImageResource就会触发空指针。
导致findViewById返回null的常见原因:

  • 传入Adapter的layoutId对应的Recycler item布局文件中,不存在id为add_light_icon的ImageView控件
  • 控件id拼写错误,和布局文件中定义的id不一致
  • 导入了错误的R类,导致代码中引用的R.id.add_light_icon不是当前模块下的对应控件id
  • 存在多item视图类型时,部分类型的item布局未添加该id的控件,滑动到对应item时触发异常
排查步骤
  • 打开构造Adapter时传入的layoutId对应的XML布局文件,全局搜索add_light_icon,确认该id对应的控件是ImageView类型,且直接属于当前item布局,而非其他布局(Activity布局、弹窗布局、其他列表item布局)
  • 核对id拼写,确保代码中引用的id和布局中定义的id完全一致,无大小写错误、字符遗漏
  • 检查文件头部的R类导入语句,确保导入的是当前项目模块的R类,而非其他依赖库/模块的R类
  • 如果Adapter实现了多viewType逻辑,逐一检查所有类型的item布局,确认都包含对应id的ImageView控件
修复方案
  1. 修正布局匹配问题
    在对应的Recycler item布局文件中添加对应id的ImageView控件,示例:
<ImageView
    android:id="@+id/add_light_icon"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:contentDescription="收藏按钮"
    android:src="@drawable/ic_add_light"/>
  1. 增强代码健壮性
    参考你对bgName、bgEditor的处理方式,将ViewHolder中通过findViewById初始化的控件都声明为可空类型,使用安全调用符?.执行操作,避免id匹配失败时直接崩溃。
    修改后的ViewHolder代码:
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    val bgImage: ImageView? = view.findViewById(R.id.image_item)
    val bgName: TextView? = view.findViewById(R.id.name_item)
    val bgEditor: TextView? = view.findViewById(R.id.editor_item)
    val bgFavIcon: ImageView? = view.findViewById(R.id.add_light_icon)
}

对应修改onBindViewHolder中的控件调用逻辑:

// Glide加载图片逻辑
holder.bgImage?.let {
    Glide.with(context).load(Uri.parse(currentBg.image_url)).into(it)
}

// 收藏状态图标设置逻辑
if (currentBg.faved) {
    holder.bgFavIcon?.setImageResource(R.drawable.ic_check)
} else {
    holder.bgFavIcon?.setImageResource(R.drawable.ic_add_light)
}

// 收藏按钮点击事件
holder.bgFavIcon?.setOnClickListener {
    currentBg.faved = !currentBg.faved
    val repo = BgRepository()
    repo.updateBg(currentBg)
}
  1. 优化建议
    *不要在onBindViewHolder中重复创建BgRepository实例,会产生大量无意义的内存开销,可以将Repository实例通过Adapter构造函数传入,全局复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:31:06