Home > Mobile >  How to change Activity when clicking an item of my RecyclerView?
How to change Activity when clicking an item of my RecyclerView?

Time:02-19

I have a RecyclerView that gets information from FirebaseFirestore, I need that when I click on an item I change the activity and add a putExtra. I try to call an Intent inside the Adapter of my RecyclerView but I get the error 'Function declaration must have a name' and 'Expecting member declaration'.

How can I change the Activity and add a putExtra by clicking on an Item in the RecyclerView?

this is MyAdapter

package com.example.atipicoapp

import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item.view.*

class MyAdapter(private val platoList : ArrayList<Plato>,
                private val itemClickListener: OnPlatoClickListener
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    interface OnPlatoClickListener{
        fun onItemClick(nombre: String)
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {

        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)

        itemView.platoTouch.setOnClickListener(View.OnClickListener { v: View ->
            

        })

        return MyViewHolder(itemView)

    }

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

        val plato : Plato = platoList[position]
        holder.platoName.text = plato.platoName
        holder.platoDescription.text = plato.platoDescription
        holder.platoPrecio.text = plato.platoPrecio.toString()
        holder.platoCantidad.text = plato.platoCantidad.toString()

    }

    override fun getItemCount(): Int {

        return platoList.size

    }

    public class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){


        val platoName : TextView = itemView.findViewById(R.id.platoNombre)
        val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
        val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)

        val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)
        
        platoCantidad.setOnClickListener(View.OnClickListener {
            val intent = Intent(itemView.getContext(),SlotActivity::class.java)itemView.getContext().startActivity(intent)})


    }
}

CodePudding user response:

    override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
        when (holder) {
            is MyViewHolder -> {
                holder.bind(platoList[position])
            }
        }
    }

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

        val platoName : TextView = itemView.findViewById(R.id.platoNombre)
        val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
        val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)

        val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)

        private val mActivity = itemView.context as Activity
        private val intent = Intent(mActivity, SlotActivity::class.java)

        fun bind(plato: Plato) {
            platoName.text = plato.platoName
            platoDescription.text = plato.platoDescription
            platoPrecio.text = plato.platoPrecio.toString()
            platoCantidad.text = plato.platoCantidad.toString()

            platoCantidad.setOnClickListener {
                intent.putExtra("key", value)
                mActivity.startActivity(intent)
            }
        }
    }

Note: it is much better to use English in variable names and comments so that developers who read your code later can easily understand it.

CodePudding user response:

You're getting an error here because you have two lines of code jammed together on one line.

val intent = Intent(itemView.getContext(),SlotActivity::class.java)itemView.getContext().startActivity(intent)})

A better way to handle this is to expose your click as a listener that the Activity (or Fragment) can implement. It would be more versatile if you change your listener function to use the item type as the parameter instead of a name String explicitly, so I would change it like this. Also, if you mark it as a fun interface, you can use more concise syntax when you define it in your Activity.

fun interface OnPlatoClickListener{
    fun onItemClick(item: Plato)
}

Then in your view holder, add a parameter for the item so the click listener you put on your view can pass the item to the Activity's OnPlatoClickListener. Mark the view holder class as inner so it has access to the itemClickListener property of the adapter.

inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
    var item: Plato? = null

    val platoName : TextView = itemView.findViewById(R.id.platoNombre)
    val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
    val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)

    val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)
    
    // maybe you should set this on itemView instead so the whole row is clickable
    platoCantidad.setOnClickListener {
        item?.let(itemClickListener::onItemClick)
    }

}

In onBindViewHolder you need to pass the item to the holder:

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

    val plato : Plato = platoList[position]
    with(holder) {
        item = plato
        platoName.text = plato.platoName
        platoDescription.text = plato.platoDescription
        platoPrecio.text = plato.platoPrecio.toString()
        platoCantidad.text = plato.platoCantidad.toString()
    }
}

Then in your Activity (or Fragment), you can set a listener on the adapter when you create it:

val adapter = MyAdapter(theDataList) { clickedItem ->
    val name = clickedItem.platoName
    val intent = Intent(this@YourActivityName, SlotActivity::class.java)
    // do something with name and intent?...
    startActivity(intent)
}
// ...
  • Related