lateinit属性侦听器尚未初始化

时间:2019-12-21 14:22:03

标签: android kotlin android-recyclerview recycler-adapter

我正在尝试将onclick侦听器添加到recyclerview项,但是我不断收到错误消息,指出该侦听器尚未初始化,但已初始化,我在做什么错了。

注意:回收站视图是嵌套的回收站视图,并且正在将onclick添加到子回收站视图

这是我的适配器的外观

class ProductAdapter(private val productModel: List<Product>): RecyclerView.Adapter<ProductAdapter.ProductView>(){

    private lateinit var listener: OnItemClickListener

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductView {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.product_item, parent, false)
        return ProductView(view, productModel, listener)
    }

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

    override fun onBindViewHolder(holder: ProductView, position: Int) {
        var product = productModel[position]
        //
        holder.product = listOf(product)

    }

    class ProductView(itemView: View, var product: List<Product>, listener: OnItemClickListener) : RecyclerView.ViewHolder(itemView){
        //

        init {
            itemView.setOnClickListener {
                listener.onButtonClick(product[0])
            }
        }

    }

    interface OnItemClickListener{
        fun onButtonClick(productModel: Product)
    }

    fun setOnItemClickListener(listener: OnItemClickListener){
        this.listener = listener
    }

}

这就是在我的片段中实现它的方式

private fun addToCart(){
        productAdapter?.setOnItemClickListener(object : ProductAdapter.OnItemClickListener {
            override fun onButtonClick(productModel: Product) {
                Log.v("Clicked", ""+productModel.productName)

            }

        })
    }

更新:我将侦听器设置为可为空,不再收到错误,但单击后未记录任何内容

private var listener: OnItemClickListener? = null

3 个答案:

答案 0 :(得分:0)

private lateinit var listener: OnItemClickListener

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductView {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.product_item, parent, false)
    return ProductView(view, productModel, listener)
}

在使用listener之前,需要对其进行初始化。您正在onCreateViewHolder()中使用它。将listener附加到ProductAdapter之前,请确保初始化RecyclerView

答案 1 :(得分:0)

代替使用setOnItemClickListener(),您可以在构造适配器时将侦听器设置为on。这将确保您始终为适配器设置点击监听器:

class ProductAdapter(private val productModel: List<Product>, listener: OnItemClickListener): RecyclerView.Adapter<ProductAdapter.ProductView>(){
    // ...
}

另一个选择是使private lateinit var listener: OnItemClickListener可为空。但是,如果必须设置侦听器,则不是一个好习惯:

class ProductAdapter(private val productModel: List<Product>): RecyclerView.Adapter<ProductAdapter.ProductView>(){

    private var listener: OnItemClickListener? = null
    // ...
}

答案 2 :(得分:0)

这里的主要问题是您在构造函数中将listener传递给ProductView并在init块中使用它,在您设置onCreateViewHolder之前从listener调用

因此,要解决此问题,您有两种选择

1-使listener可为空,并在需要时进行设置,例如

private var listener: OnItemClickListener?

然后在使用时

class ProductView(itemView: View, var product: List<Product>, listener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView){
        val foodImg: ImageView = itemView.findViewById(R.id.foodImg)
        val foodName: TextView = itemView.findViewById(R.id.foodName)
        val foodDesc: TextView = itemView.findViewById(R.id.foodDesc)
        val foodPrice: TextView = itemView.findViewById(R.id.foodPrice)
        private val addToCart: ImageView = itemView.findViewById(R.id.addToCart)
        private lateinit var repository: MainRepository


        init {
            itemView.setOnClickListener {
                listener?.onButtonClick(product[0])
            }
        }

    }

2-在适配器构造函数中传递OnItemClickListener

class ProductAdapter(private val productModel: List<Product>, private val listener: OnItemClickListener): RecyclerView.Adapter<ProductAdapter.ProductView>(){
 private lateinit var listener: OnItemClickListener //remove this listener
.....

}

您可以像这样初始化适配器

val adapter = ProductAdapter(productModel, object : ProductAdapter.OnItemClickListener {
            override fun onButtonClick(productModel: Product) {
                Log.v("Clicked", ""+productModel.productName)

            }

        })

实际上我更喜欢第二选择。