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
相关产品推荐
相关产品推荐

