Repeating Items in RecyclerView - android-studio

I know this question has been asked before, but honestly, I can't find the right solution. I don't know why after scrolling the RecyclerView, adapter makes same data over and over again.
I have a project that uses retrofit to get data from an api-server and show it on a RecyclerView. I'm receiving data correctly and the received list doesn't have any repeated items. Just before passing the data to RecyclerAdapter in my Activity, I Log the data and still everything looks good. So I think the problem is the Adapter.
PS. While I'm running the app and scrolling RecyclerView to the end, "Log" inside the adapter, returns unique items. I think I have a mistake in binding data.
Log.i("test",data[position].toString())
Here is my Adapter:
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailrecipes.apiManager.model.category
import com.example.cocktailrecipes.databinding.TemplateRecyclerViewCategoryBinding
class CategoryAdapter(private val data: List<category.Drink>) : RecyclerView.Adapter<CategoryAdapter.Holder>() {
lateinit var binding: TemplateRecyclerViewCategoryBinding
inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindData(drinkData:category.Drink) {
binding.txtDrinkName.text = drinkData.strDrink
Glide.with(binding.root)
.load(drinkData.strDrinkThumb)
.into(binding.imgDrink)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
binding = TemplateRecyclerViewCategoryBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return Holder(binding.root)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
Log.i("test",data[position].toString())
holder.bindData(data[position])
}
override fun getItemCount(): Int {
return data.size
}
}

Thx so much #Tenfour04
I use your advice and my problem solved:
class CategoryAdapter(private val data: List<category.Drink>) : RecyclerView.Adapter<CategoryAdapter.Holder>() {
inner class Holder(private val binding: TemplateRecyclerViewCategoryBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindData(drinkData:category.Drink) {
binding.txtDrinkName.text = drinkData.strDrink
Glide.with(binding.root)
.load(drinkData.strDrinkThumb)
.into(binding.imgDrink)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = TemplateRecyclerViewCategoryBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return Holder(binding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
Log.i("test",data[position].toString())
holder.bindData(data[position])
}
override fun getItemCount(): Int {
return data.size
}
}

For the Holder make itemView a val, and then in bindData call:
itemView.txtDrinkName.text = drinkData.strDrink
binding is just a class property, I am not sure how it would know what view is associate with a specific holder.

here is solution:-
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}

Related

Confused about inheriting RecyclerView.Adapter and RecyclerView.ViewHolder abstract classes (Kotlin/Android Studio)

I am confused about the inheritance of the RecyclerView.Adapter and RecyclerView.ViewHolder abstract classes. In the code below I inherited the abstract class RecyclerView.Adapter, hence I had to override the fun onCreateViewHolder, fun onBindViewHolder and fun getItemCount. I understand that part, however, why am I not required to override the abstract class RecyclerView.ViewHolder(view) as well?
I don't fully understand the explanation from the android studio docs.
class ItemAdapter(
private val context: Context,
private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
// create a new view
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return ItemViewHolder(adapterLayout)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
override fun getItemCount() = dataset.size

Problem with RecyclerView OnClick (kotlin)

sorry for the inconvenience, but this is my first time trying this. I've been trying on doing this app which it has a recyclerView which I intent it to open a chrome page. The thing is, I'm not able to implement the itemOnClickListener despite having tried a lot of videos. Could you point out where is my mistake?
My Adapter:
package com.example.practica1.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.example.practica1.R
import com.example.practica1.data.Video
class MainAdapter(private val context: Context, private val videos: List<Video>): RecyclerView.Adapter<MainAdapter.ViewHolder>(){
private lateinit var mListener: onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnClickListener(listener: onItemClickListener){
mListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cartoon, parent, false)
return ViewHolder(view, mListener)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val video = videos[position]
holder.title.text = video.data.short_title
holder.serieTitle.text = video.data.show.title
holder.durationTitle.text = video.data.video.duration + " seg"
Glide.with(context)
.load(video.data.imagepath)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(400, 400)
.centerCrop()
.into(holder.imagePrev)
}
override fun getItemCount() = videos.size
inner class ViewHolder(itemView: View, listener: onItemClickListener) : RecyclerView.ViewHolder(itemView){
val title: TextView = itemView.findViewById(R.id.videoTitle)
val serieTitle: TextView = itemView.findViewById(R.id.serieTitle)
val durationTitle: TextView = itemView.findViewById(R.id.durationTitle)
val imagePrev: ImageView = itemView.findViewById(R.id.photoPreview)
init{
itemView.setOnClickListener{
listener.onItemClick(adapterPosition)
}
}
}
}
The fragment in which I tried to implement the method:
package com.example.practica1.fragments
import android.os.Bundle
import android.util.Log
import android.util.Log.d
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView
import com.example.practica1.R
import com.example.practica1.adapter.MainAdapter
import com.example.practica1.data.ApiInterface
import com.example.practica1.data.Video
import com.example.practica1.databinding.FragmentMenuBinding
import com.haerul.bottomfluxdialog.BottomFluxDialog
import com.haerul.bottomfluxdialog.BottomFluxDialog.OnInputListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MenuFragment : Fragment() {
private var _binding: FragmentMenuBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentMenuBinding.inflate(inflater, container, false)
val view = inflater.inflate(R.layout.fragment_menu, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val retrofit = Retrofit.Builder()
.baseUrl("https://www.cartoonnetwork.com.co")
.addConverterFactory(GsonConverterFactory.create())
.build()
val api = retrofit.create(ApiInterface::class.java)
showProgress()
api.fetchAllVideos().enqueue(object : Callback<List<Video>> {
override fun onResponse(call: Call<List<Video>>, response: Response<List<Video>>) {
if (response.isSuccessful()) {
d("daniel", "onResponse ${response.body()!![0].id}")
if (response.body()!!.size > 0) {
showData(response.body()!!)
getResult(true, "Sucess")
} else
getResult(false, response.message())
hideProgress()
}
}
override fun onFailure(call: Call<List<Video>>, t: Throwable) {
d("daniel", "onFailure")
getResult(false, "Request Timeout. Please Try Again!")
hideProgress()
}
})
binding.search.setOnClickListener { v -> showDialog(v) }
}
fun showData(videos: List<Video>){
val test: RecyclerView = requireActivity().findViewById(R.id.recycler_viewMenu)
var adap = MainAdapter(requireContext(), videos)
test.apply{
adapter = adap
}
adap.setOnClickListener(object: MainAdapter.onItemClickListener{
override fun onItemClick(position: Int){
d("test", "test")
}
})
}
fun showProgress(){
binding.swipeRefresh.setRefreshing(true)
binding.emptyView.setVisibility(View.GONE)
binding.shimmer.startShimmer()
binding.shimmer.setVisibility(View.VISIBLE)
binding.recyclerViewMenu.setVisibility(View.GONE)
}
fun hideProgress(){
binding.swipeRefresh.setRefreshing(false)
binding.shimmer.stopShimmer()
binding.shimmer.setVisibility(View.GONE)
binding.recyclerViewMenu.setVisibility(View.VISIBLE)
}
fun getResult(status: Boolean, message: String){
if(!status) {
binding.emptyView.setVisibility(View.VISIBLE)
binding.textEmptyErr.setText(message)
}
else
binding.emptyView.setVisibility((View.GONE))
}
private fun showDialog(view: View){
BottomFluxDialog.inputDialog(requireActivity())
.setTextTitle("Input Title")
.setTextMessage("This is an input message")
.setRightButtonText("SUBMIT")
.setInputListener(object : OnInputListener {
override fun onSubmitInput(text: String?) {
val bundle = Bundle()
bundle.putString("search", text)
Navigation.findNavController(view)
.navigate(R.id.action_menuFragment_to_listFragment, bundle)
}
override fun onCancelInput() {}
})
.show()
}
}
Thanks!
There is no such common thin like OnItemClickListener for RecyclerView, so you have to design your own. It shouldn't be hard to implement by hand, though. What you can do, is that you can Just set OnClickListener to the whole item view and delegate it clicks to upper lambda.
class YourAdapter(
private val listener: (Video) -> Unit,
private val videos: List<Video>,
): ... {
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
...
holder.itemView.setOnClickListener { v ->
if (position != RecyclerView.NO_POSITION) {
listener(videos[position])
}
}
}
}
There are no noticeable side-effects of swapping View.OnClickListener in onBindViewHolder() method.
Also, few suggestions:
Read about ListAdapterhere. Looks like it perfect fit for your usecase.
Use getAbsoluteAdapterPosition() instead of adapterPosition() method within ViewHolder, as adapters are designed to be combined. Read more about ConcatAdapter here.
You don't need to pass Context to adapter constructor. View already has context, so you can query context by calling viewHolder.itemView.context.
Make sure to use your binding. It looks like you creating your binding in MenuFragment, but later you are getting RecyclerView by id in an old-fashioned way.
Don't create adapters, that require data for creation. Instead, pass and update data as you requested from the backend. RecyclerView.Adapter is designed to be reused.

problems with sending data - recyclerview

good, I'm learning kotlin
I am wanting to send the data from one recyclerview to another recyclerview. By pressing a button, the name, price and photo, I want it to be sent to the other recyclerview and then another one and thus fill the list, what is the error?
this is my code from my first recyclerview, which sends data, I am using bundle in the adapter to send it to the other recyclerview
class Adaptador_Caras(private var caras: ArrayList<Caras>,private var context: Context):RecyclerView.Adapter<Adaptador_Caras.ViewHolder>() {
class ViewHolder(var vista:View,var contexto:Context):RecyclerView.ViewHolder(vista){
fun bind(caras:Caras){
vista.ivFoto.setImageResource(caras.foto)
vista.tvNombre.text=caras.nombre
vista.tvPrecio.text=caras.precio.toString()
vista.btnIngresar.setOnClickListener {
val intent=Intent(contexto,RecyclerView::class.java)
intent.putExtra("FOTO", caras.foto)
intent.putExtra("NOMBRE",caras.nombre)
intent.putExtra("PRECIO",caras.precio)
contexto.startActivity(intent)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.lista_caras,parent,false),context)
}
override fun getItemCount(): Int {
return caras.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(caras[position])
}
}
this is the main activity, where the images are loaded
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rvCaras.layoutManager=LinearLayoutManager(this)
rvCaras.adapter=Adaptador_Caras(misCaras(),this)
}
private fun misCaras():ArrayList<Caras>{
var caras=ArrayList<Caras>()
caras.add(Caras("lucas",10,R.drawable.foto_01))
caras.add(Caras("toluca",10,R.drawable.foto_02))
caras.add(Caras("jiana",10,R.drawable.foto_03))
caras.add(Caras("joina",10,R.drawable.foto_04))
caras.add(Caras("toto",10,R.drawable.foto_05))
return caras
}
}
this is the adapter of the activity that receives the data
class AdaptadorRecibir(private var recibir:ArrayList<Recibir>,private var context:Context):RecyclerView.Adapter<AdaptadorRecibir.ViewHolder>() {
class ViewHolder(var vista: View, var contexto:Context):RecyclerView.ViewHolder(vista){
fun bind(recibir: Recibir){
vista.ivFotoR.setImageResource(recibir.fotoR)
vista.tvNombreR.text=recibir.nombreR
vista.tvPrecioR.text=recibir.precioR.toString()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.lista_recibir,parent,false),context)
}
override fun getItemCount(): Int {
return recibir.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(recibir[position])
}
}
this is the activity receive data , here I receive the data
class RecibirRecycler : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recibir_recycler)
val parametros=this.intent.extras
if (parametros!=null){
val valor1=parametros.getInt("FOTO")
val valor2=parametros.getString("NOMBRE")
val valor3=parametros.getString("PRECIO")
tvNombreR.text=valor2
tvPrecioR.text=valor3
ivFotoR.setImageResource(valor1)
}
}
thanks for your help
Send data with bundle
Inside ViewHolder class:
vista.btnIngresar.setOnClickListener {
startActivity(
Intent(contexto, RecibirRecycler::class.java).putExtras(
bundleOf(
"FOTO" to (caras.foto?: 0),
"NOMBRE" to (caras.nombre?:""),
"PRECIO" to (caras.precio?:"))
))
}

OnItem click not working properly after clicking on the item in Recyclerview

I have tried to implement search functionality in the recycler view.for that I have written below code in My "Main.kt" class
search functionality is working fine for me,
the issue is when I am searching the item from the list and clicking on that item I am getting the wrong position.
please help me with this issue.
adapter = DynamicListAdapter(dynamicList)
dynamic_list_recyclerview.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL,false) as RecyclerView.LayoutManager
dynamic_list_recyclerview.adapter = adapter
adapter!!.setRecyclerViewItemClickLister(this)
i have taken edit text and added the addTextChangedListener
edt_search_dynamic.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(editable: Editable?) {
filter(editable.toString())
}
})
fun filter(text : String){
var filteredList = mutableListOf<DynamicModel>()
for(list in dynamicList){
if(list.vehicleno.toLowerCase().contains(text.toLowerCase())){
filteredList.add(list)
}
}
adapter?.filterList(filteredList)
}
and this is my adapter class
class DynamicListAdapter (var dynamiclist : List<DynamicModel>) : RecyclerView.Adapter<DynamicListAdapter.DynamicViewHolder>() {
var recyclerViewOnItemClickListener : RecyclerViewOnItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DynamicViewHolder {
val inflatedView = LayoutInflater.from(parent.context)
.inflate(R.layout.singlerowdynamiclist,parent,false)
return DynamicViewHolder(inflatedView,dynamiclist)
}
override fun getItemCount(): Int {
return dynamiclist.size
}
override fun onBindViewHolder(holder: DynamicViewHolder, position: Int) {
holder.bindItem(dynamiclist[position])
}
inner class DynamicViewHolder(itemView : View, var dynamiclists : List<DynamicModel>) : RecyclerView.ViewHolder(itemView), View.OnClickListener
{
private var txtStatus : TextView? = null
init {
txtStatus = itemView.findViewById(R.id.txtStatus)
itemView.setOnClickListener(this)
}
fun bindItem(dynamiclist : DynamicModel){
txtStatus?.text = dynamiclist.vehiclestatus
}
override fun onClick(view: View?) {
when(view){
itemView -> if(recyclerViewOnItemClickListener!= null){
recyclerViewOnItemClickListener!!.onItemClick(adapterPosition,view)
}
}
}
}
// method of outer class
fun setRecyclerViewItemClickLister(onRecyclerviewItemClickListener : RecyclerViewOnItemClickListener){
this.recyclerViewOnItemClickListener = onRecyclerviewItemClickListener
}
// for filter the list
fun filterList(dymaniclist : List<DynamicModel>){
this.dynamiclist = dymaniclist
notifyDataSetChanged()
}
}
and this is the interface which I have implemented in my Main.kt class
interface RecyclerViewOnItemClickListener {
fun onItemClick(position : Int, view: View)
}
You won't get the desired position (the position from the unfiltered list) after applying your filters, because you lose that information when creating a new filtered list and putting it inside the DynamicListAdapter.
Let's say inside the adapter we have a list of the following items:
val dynamicList = listOf(
"#0 A", // 0th position
"#1 B", // 1st position
"#2 AB" // 2nd position
)
Now let's use your filter method:
filter("A")
This ends with replacing the old dynamicList inside the DynamicListAdapter with a completely new filteredList, which looks like this:
val filteredList = listOf(
"#0 A", // 0th position
"#2 AB", // 1st position
)
Now when clicking the #2 AB you will get position of value 1 (not desired 2) as it is the item's index in the new filteredList.
There are multiple ways of how to achieve what you want, but if you only want data from the clicked item, just return the object instead of its position on the item click:
interface RecyclerViewOnItemClickListener {
fun onItemClick(dynamicModel: DynamicModel, view: View)
}
// inside DynamicListAdapter
inner class DynamicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItem(dynamiclist : DynamicModel) {
with (itemView) {
txtStatus.text = dynamiclist.vehiclestatus
setOnClickListener {
recyclerViewOnItemClickListener?.onItemClick(dynamiclist, this)
}
}
}
}
However if you need to return the position and the above is not an option, I would suggest leaving the original list in the adapter and letting it handle filtering by itself, for example:
// _dynamicList is always the original list
class DynamicListAdapter (private val _dynamicList: List<DynamicModel>) : RecyclerView.Adapter<DynamicListAdapter.DynamicViewHolder>() {
var recyclerViewOnItemClickListener : RecyclerViewOnItemClickListener? = null
var filterText: String = ""
set(value) {
field = value
notifyDataSetChanged()
}
// return original list (_dynamicList) if no filter should be applied or return the filtered list based on the filterText
private val dynamicList: List<DynamicModel>
get() = if (filterText.isBlank()) _dynamicList
else _dynamicList.filter { it.vehicleno.contains(filterText, ignoreCase = true) }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DynamicViewHolder {
val inflatedView = LayoutInflater.from(parent.context).inflate(R.layout.singlerowdynamiclist,parent,false)
return DynamicViewHolder(inflatedView)
}
override fun getItemCount(): Int {
return dynamicList.size
}
override fun onBindViewHolder(holder: DynamicViewHolder, position: Int) {
holder.bindItem(dynamicList[position])
}
inner class DynamicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItem(dynamicModel: DynamicModel) {
with (itemView) {
txtStatus.text = dynamicModel.vehiclestatus
// get the item's original position (before filtering)
val position = _dynamicList.indexOf(dynamicModel)
setOnClickListener {
recyclerViewOnItemClickListener?.onItemClick(position, this)
}
}
}
}
}
// filter method
fun filter(text: String){
adapter?.filterText = text
}
I put my solution it might help somebody.
Given: recyclerView is working fine.
Problem: on item click is not working after implementing searchview.
solution: add mAdapter.setOnItemClickListener again inside onQueryTextChange as below:
#Override
public boolean onQueryTextChange(String newText) {
mAdapter = new MyAdapter(getApplicationContext(), OtherInofYouWantToPass);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view, MyObj obj, int position) {
{ add your work here}
}
});
return false;
}

Studio shows an error when I try to startActivity() from Recycler View Adapter

Building my first app and hitting an error I can't figure out. I have a recycler view that shows a list of cards. I want to click the card and open another activity.
Here is my code:
import android.content.Context
import android.content.Intent
import android.support.v4.content.ContextCompat.startActivity
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import kotlinx.android.synthetic.main.list_tank_item.view.*
class TankAdapter(val context: Context, val tanks: List<Tank>) : RecyclerView.Adapter<TankAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.list_tank_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return tanks.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val tank = tanks[position]
holder.setData(tank, position)
}
inner class ViewHolder(itemview: View) : RecyclerView.ViewHolder(itemview) {
var currentTank: Tank? = null
var currentPosition: Int = 0
init {
itemView.setOnClickListener{
val intent = Intent(context, TankOverviewActivity::class.java)
var tank_id = currentTank._id.toString()
intent.putExtra("tank_id", tank_id)
startActivity(intent)
}
itemView.imgEdit.setOnClickListener{
Toast.makeText(context, currentTank!!.tank_name + " Edit button clicked!", Toast.LENGTH_LONG).show()
}
}
fun setData(tank: Tank?, position: Int) {
itemView.txvTankName.text = tank!!.tank_name
itemView.txvTankCapacity.text = tank!!.tank_capacity
itemView.txvTankType.text = tank!!.tank_type
this.currentTank = tank
this.currentPosition = position
}
}
}
And here a screen of of android studio:
Android Studio problem
What am I doing wrong?
Try as follow
import ...
//use your context as member of your class put private as modifier
class TankAdapter(private val context: Context, val tanks: List<Tank>) : RecyclerView.Adapter<TankAdapter.ViewHolder>() {
...
inner class ViewHolder(itemview: View) : RecyclerView.ViewHolder(itemview) {
...
init {
itemView.setOnClickListener {
...
//call startActivity from context
context.startActivity(intent)
}
...
}
...
}
}

Resources