【问题标题】:lateinit property onItemClickCallback has not been initializedlateinit 属性 onItemClickCallback 尚未初始化
【发布时间】:2019-10-19 13:15:17
【问题描述】:

我是 android 和 kotlin 的新手。我正在使用接口为我的 cardViewAdapter 制作 onclick 监听器,这样我就可以从我的活动中覆盖它的回调。但是在模拟器上运行它并单击每个 itemView 时,我收到错误“lateinit property onItemClick has not been initialized”。

在我的代码中,我尝试在函数中对其进行初始化。在此之前,我从另一个人那里尝试了这个答案,所以https://stackoverflow.com/a/46076355/7587265 但是onclick不起作用

这是我的 MainActivity.kt

rvMotor.layoutManager = GridLayoutManager(this, 2)
val recycleViewAdapter = CardViewMainAdapter(listMotor)
recycleViewAdapter.setOnItemClickCallback(object : CardViewMainAdapter.OnItemClickCallback{
    override fun onItemClicked(data: Motor) {
        val intent = Intent(this@MainActivity, DetailActivity::class.java)
        intent.putExtra(DetailActivity.EXTRA_ID, data.id)
        startActivity(intent)
    }
})

rvMotor.adapter = recycleViewAdapter

这是我的 CardViewMainAdapter.kt

class CardViewMainAdapter(private val listMotors: ArrayList<Motor>) :
    RecyclerView.Adapter<CardViewMainAdapter.CardViewMainViewHolder>() {

    private lateinit var onItemClickCallback : OnItemClickCallback

    fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback){
        this.onItemClickCallback = onItemClickCallback
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewMainViewHolder {
        val view: View = LayoutInflater.from(parent.context).inflate(R.layout.cardview_main, parent, false)
        return CardViewMainViewHolder(view)
    }

    override fun getItemCount(): Int {
        return listMotors.size
    }

    override fun onBindViewHolder(holder: CardViewMainViewHolder, position: Int) {
        val motor = listMotors[position]

        holder.cvMainName.text = motor.name
        Glide.with(holder.itemView.context)
            .load(motor.image)
            .apply(RequestOptions().override(350, 550))
            .into(holder.cvMainImage)

        holder.itemView.setOnClickListener{
            onItemClickCallback.onItemClicked(listMotors[holder.adapterPosition])
        }
    }

    inner class CardViewMainViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        var cvMainImage: ImageView = itemView.findViewById(R.id.cardview_main_img)
        var cvMainName: TextView = itemView.findViewById(R.id.cardview_main_txt)
    }

    interface OnItemClickCallback {
        fun onItemClicked(data: Motor)
    }
}

【问题讨论】:

    标签: android kotlin callback kotlin-lateinit


    【解决方案1】:

    根据文档:在初始化之前访问 lateinit 属性会引发一个特殊异常,该异常清楚地标识正在访问的属性以及它尚未初始化的事实。

    检查一个 lateinit 变量是否已经被初始化, 在对该属性的引用上使用 .isInitialized

    我不知道为什么它会导致这里出现问题。我认为您的代码很好,但我可以为您解决问题。

    在您的情况下,您可以通过两种方式解决问题。

    1. 只需在点击监听器中添加一个 if 条件来检查它是否被集成。

     holder.itemView.setOnClickListener{
    
            //Check whether it is Initialized or not
            if(::onItemClickCallback.isInitialized){
                onItemClickCallback.onItemClicked(listMotors[holder.adapterPosition])
            }
        }
    

    2. 删除 lateint 并将其设为可为空。

        //Make it as nullable
        private  var onItemClickCallback : OnItemClickCallback? = null
    
        holder.itemView.setOnClickListener {
    
            holder.itemView.setOnClickListener {
                // add ? for handling nullable 
                onItemClickCallback?.onItemClicked(listMotors[holder.adapterPosition])
            }
    
        }
    

    【讨论】:

    • 感谢您的建议,我最终在适配器参数中声明了 onItemClickCallback
    • 好的,很高兴听到您解决了问题。
    【解决方案2】:

    我最终在适配器参数中初始化 onItemClickCallback,而不是从函数中。我以为我已经尝试过这种方式,但是由于未知原因,它以前不起作用。感谢所有回复。 这是我的活动

    val recycleViewAdapter = CardViewMainAdapter(listMotor, object : CardViewMainAdapter.OnItemClickCallback{
                override fun onItemClicked(data: Motor) {
                    val intent = Intent(this@MainActivity, DetailActivity::class.java)
                    intent.putExtra(DetailActivity.EXTRA_ID, data.id)
                    startActivity(intent)
                }
            })
    
    rvMotor.adapter = recycleViewAdapter
    

    这是我的适配器

    class CardViewMainAdapter(private val listMotors: ArrayList<Motor>, private val onItemClickCallback: OnItemClickCallback) :
        RecyclerView.Adapter<CardViewMainAdapter.CardViewMainViewHolder>() {
    

    【讨论】:

      猜你喜欢
      • 2017-03-03
      • 1970-01-01
      • 2020-12-31
      • 2021-06-11
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多