RecyclerView itemClickListener in Kotlin [closed]

Solution 1:

My solution is like a combination of the previous ones with a super clean call from the activity.

ContactAdapter:

class ContactAdapter @Inject constructor() : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {

    var onItemClick: ((Contact) -> Unit)? = null
    var contacts: List<Contact> = emptyList()

    ...

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val contact = contacts[position]

        holder.email.text = contact.email
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val email: TextView = itemView.email

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

ContactActivity:

override fun setupRecyclerAdapter() {
    recyclerView.adapter = contactAdapter
    recyclerView.layoutManager = LinearLayoutManager(this)

    contactAdapter.onItemClick = { contact ->

        // do something with your item
        Log.d("TAG", contact.email)
    }
}

Solution 2:

I have a little bit different approach. You can create an extension for your ViewHolder

fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(getAdapterPosition(), getItemViewType())
    }
    return this
}

Then use it in adapter like this

class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    val items: MutableList<String> = arrayListOf()

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder? {
        val inflater = LayoutInflater.from(parent!!.getContext())
        val view = inflater.inflate(R.layout.item_view, parent, false)
        return MyViewHolder(view).listen { pos, type ->
            val item = items.get(pos)
            //TODO do other stuff here
        }
    }

    override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {

    }

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


    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    }
}

I am working with my colleagues on library providing such extensions.