Home > Software design >  Itemclicklistener on recyclerview item in kotlin
Itemclicklistener on recyclerview item in kotlin

Time:01-31

How to move from one activity to another by clicking on recyclerview item and also pass some details of the clicked item in intent?

This is how my adapter class looks like

var onItemClick : ((Contest)->Unit)?=null
private lateinit var mListener: onItemClickListener
interface onItemClickListener{
    fun onItemClick(position: Int)
}

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



inner class MyViewHolder(itemView:View,listener: onItemClickListener):RecyclerView.ViewHolder(itemView ){
    val name: TextView = itemView.findViewById(R.id.card_title)
    val time: TextView = itemView.findViewById(R.id.card_time)
    val venue: TextView = itemView.findViewById(R.id.card_venue)
    val team: TextView = itemView.findViewById(R.id.card_team_type)
    val prize: TextView = itemView.findViewById(R.id.card_prize)
    val entry: TextView = itemView.findViewById(R.id.card_entry_division)
    val join_btn: Button = itemView.findViewById(R.id.card_join_btn)

    init {
        itemView.setOnClickListener{
            onItemClick?.invoke(contestlist[adapterPosition])
        }
    }

    }

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.contest_item,parent,false)
    return MyViewHolder(itemView,mListener )
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    val contests = contestlist[position]
    holder.name.text = contestlist[position].name
    holder.entry.text = contestlist[position].entry
    holder.prize.text = contestlist[position].prize
    holder.team.text = contestlist[position].team
    holder.time.text = contestlist[position].time
    holder.venue.text = contestlist[position].venue
    holder.join_btn.text = contestlist[position].total_entry


}

CodePudding user response:

I think you've confused yourself by adding two different ways to set a listener.

  1. Your function property var onItemClick
  2. Your functional interface property private lateinit var mListener.

You need to delete one or the other. The first one is the one you should keep, because you are breaking a couple of conventions with your implementation of the second one, by misusing lateinit and by hiding a property behind setter function.

You're already correctly calling onItemClick?.invoke(contestlist[adapterPosition]) in the click listener of each view holder's root view. You just need to delete this stuff:

private lateinit var mListener: onItemClickListener
interface onItemClickListener{
    fun onItemClick(position: Int)
}

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

and delete the listener parameter in your ViewHolder constructor.

The class that creates the adapter (your Activity or Fragment) can set a lambda as the value of your adapter's onItemClick property and do the effect there:

adapter.onItemClick = { contest ->
    // do something like open another fragment
}
  • Related