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

lateinit属性myListener未初始化问题求助(RecyclerView适配器场景)

解决lateinit属性未初始化异常

错误信息

kotlin.UninitializedPropertyAccessException: lateinit property myListener has not been initialized
at com.example.fitnesscult.MyAdapter.onCreateViewHolder(MyAdapter.kt:30)
at com.example.fitnesscult.MyAdapter.onCreateViewHolder(MyAdapter.kt:11)

适配器代码

package com.example.fitnesscult

import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView

class MyAdapter(var yogaArrayList: ArrayList<YogaData>, var context : Activity ) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    private lateinit var myListener: onItemClickListener

    interface onItemClickListener {
        fun onItemClicking(position: Int)
    }

    fun setOnItemClickListener(listener : onItemClickListener){
        myListener = listener
    }

    // 创建新视图实例
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.eachyoga,parent,false)
        return MyViewHolder(itemView,myListener)
    }

    // 填充数据到视图
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        var currentItem = yogaArrayList[position]
        holder.hTitle.text = currentItem.yogaName.toString()
        holder.hImage.setImageResource(currentItem.yogaImage)
    }

    // 返回列表项数量
    override fun getItemCount(): Int {
        return yogaArrayList.size
    }

    // ViewHolder类,复用视图节省内存
    class MyViewHolder(itemView : View, listener: onItemClickListener): RecyclerView.ViewHolder(itemView) {
        val hTitle = itemView.findViewById<TextView>(R.id.yogaTittle)
        val hImage = itemView.findViewById<ShapeableImageView>(R.id.yogaImage)

        init {
            itemView.setOnClickListener {
                listener.onItemClicking(adapterPosition)
            }
        }
    }
}

问题原因

myListener用lateinit修饰,要求必须在第一次访问前完成初始化。但当前代码在onCreateViewHolder中直接传入myListener创建ViewHolder,如果在设置适配器后未调用setOnItemClickListener,就会触发未初始化异常。

解决方案

方案1:确保使用适配器前必设监听

在Activity/Fragment中创建适配器后,立即调用setOnItemClickListener,再绑定到RecyclerView:

val adapter = MyAdapter(yogaList, this)
// 先设置点击监听
adapter.setOnItemClickListener(object : MyAdapter.onItemClickListener {
    override fun onItemClicking(position: Int) {
        // 自定义点击逻辑,比如跳转详情页
    }
})
recyclerView.adapter = adapter

方案2:给监听设置默认空实现

取消lateinit,直接给myListener赋值一个空实现,避免未初始化:

// 替换原lateinit声明
private var myListener: onItemClickListener = object : onItemClickListener {
    override fun onItemClicking(position: Int) {
        // 默认无操作,后续调用setOnItemClickListener会覆盖
    }
}

方案3:将点击监听移到onBindViewHolder中

修改ViewHolder不再依赖外部传入的listener,而是在绑定数据时设置点击事件:

// 修改Adapter部分代码
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.eachyoga,parent,false)
    return MyViewHolder(itemView) // 不再传myListener
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    var currentItem = yogaArrayList[position]
    holder.hTitle.text = currentItem.yogaName.toString()
    holder.hImage.setImageResource(currentItem.yogaImage)
    
    // 在这里设置点击监听
    holder.itemView.setOnClickListener {
        myListener.onItemClicking(position)
    }
}

// 修改ViewHolder类
class MyViewHolder(itemView : View): RecyclerView.ViewHolder(itemView) {
    val hTitle = itemView.findViewById<TextView>(R.id.yogaTittle)
    val hImage = itemView.findViewById<ShapeableImageView>(R.id.yogaImage)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:32:48