Home > Software engineering >  adding onclicklistener to recycler view with viewbinding, kotlin
adding onclicklistener to recycler view with viewbinding, kotlin

Time:01-10

Trying to add an onclicklistener to the items in my recycler view, that will use an intent to open another activity. I've tried finding examples, but I can only find examples using Java or Kotlin examples that aren't using viewbinding.

package com.truuce.anotherrvtest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.GridLayoutManager

import com.truuce.anotherrvtest.databinding.ActivityHeroBinding

class HeroActivity : AppCompatActivity() {

    var binding: ActivityHeroBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHeroBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        val adapter = CardAdapter(HeroList.heroList)
        binding?.heroRV?.adapter = adapter
        binding?.heroRV?.layoutManager = GridLayoutManager(applicationContext, 3)

    }

    override fun onDestroy() {
        super.onDestroy()
        binding = null
    }
}
package com.truuce.anotherrvtest

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.truuce.anotherrvtest.databinding.HeroCardBinding

class CardAdapter(val heroList: List<Hero>) : RecyclerView.Adapter<CardAdapter.MainViewHolder>() {

    inner class MainViewHolder(val heroBinding: HeroCardBinding) :
        RecyclerView.ViewHolder(heroBinding.root) { 
        fun bindHero(hero: Hero){
            heroBinding.heroNameTV.text = hero.heroName
            heroBinding.heroIV.setImageResource(hero.image)
        }

    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {


        return MainViewHolder(HeroCardBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }


    override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
        val hero = heroList[position]
        holder.bindHero(hero)
    }


    override fun getItemCount() = heroList.size
}

tried adding View.OnClickListener to MainViewHolder, then implemented a member. OnClick(p0: View){}, but no idea how to get it working.

CodePudding user response:

You should add a functional property for a click listener in your adapter.

The Activity can set the item click listener behavior.

class CardAdapter(
    val heroList: List<Hero>,
    val itemClickListener: (Hero)->Unit
) : RecyclerView.Adapter<CardAdapter.MainViewHolder>() {

    inner class MainViewHolder(val heroBinding: HeroCardBinding) :
        RecyclerView.ViewHolder(heroBinding.root) { 
        fun bindHero(hero: Hero) = with(heroBinding) {
            heroNameTV.text = hero.heroName
            heroIV.setImageResource(hero.image)
            root.setOnClickListener { itemClickListener(hero) }
        }

    }

    //...
}
// In Activity:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHeroBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        val adapter = CardAdapter(HeroList.heroList) { hero ->
            // do something with hero item when it's clicked
        }
        binding?.heroRV?.adapter = adapter
        binding?.heroRV?.layoutManager = GridLayoutManager(applicationContext, 3)

    }
  • Related