OnClickListener in RecyclerView Adapter not initialized

I am trying to add an OnClickListener to a recycler view item i however keep getting this error

lateinit property listener has not been initialized

Here is how my adapter looks like

class CartAdapter(private val cartItems: List<CartItemEntity>? = null) : RecyclerView.Adapter<CartAdapter.CartViewHolder>() {

    private lateinit var listener: OnItemClickListener

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.cart_item, parent, false)
        return CartViewHolder(view, cartItems!!, listener)
    }

    override fun getItemCount() = cartItems!!.size

    override fun onBindViewHolder(holder: CartViewHolder, position: Int) {
        val cartItem = cartItems?.get(position)
        holder.productPrice.text = cartItem.productPrice.toInt().toString()
        holder.cart = listOf(cartItem)
    }

    class CartViewHolder(val view: View, var cart: List<CartItemEntity>, listener: OnItemClickListener) : RecyclerView.ViewHolder(view) {
        private val cartRemove: TextView = view.findViewById(R.id.cartRemove)

        init {
            cartRemove.setOnClickListener {
                listener.onItemClick(cart)
            }

        }
    }

    interface OnItemClickListener{
        fun onItemClick(cartItems: List<CartItemEntity>?)
    }

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

}

This is how i am implementing it in my Fragment

adapter!!.setOnItemClickListener(object : CartAdapter.OnItemClickListener{
            override fun onItemClick(cartItems: List<CartItemEntity>?) {
                Log.e("Cart Item", ""+ cartItems!![0].id)
            }
        })

Not sure what am doing wrong

2 answers

  • answered 2020-02-16 15:29 Рустам Бакытов

    create constructor inside your Adapter

      public Adapter(ListenerAdapter click) {
        this.click = click;
    }
    

    and send object from fragment when you create recyclerView

    private void initRecyclerView(View view) {
        adapter = new Adapter(this);}   
    

    in my case I create View Holder how another class and i have to send listener to ViewHolder too, like below

     @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.item_main_activity, parent, false);
        // we send part of ListenerAdapter to ViewHolder
        return new ViewHolder(view,click);
    }
    

  • answered 2020-02-16 16:31 Vincent Tirgei

    You can add the listener as part of your CartAdapter constructor

    class CartAdapter(private val cartItems: List<CartItemEntity>? = null, itemListener: OnItemClickListener) : RecyclerView.Adapter<CartAdapter.CartViewHolder>() {
    
        private val listener: OnItemClickListener = itemListener
    
        ...
    
        interface OnItemClickListener{
            fun onItemClick(cartItems: List<CartItemEntity>?)
        }
    }
    

    Then from your activity, pass the listener when you initialize the adapter

        val adapter = CartAdapter(itemList, object: CartAdapter.OnItemClickListener {
            override fun onItemClick(cartItems: List<CartItemEntity>?) {
                Log.e("Cart Item", ""+ cartItems!![0].id)
            }
        })