0

I have an adapter for my RecyclerView where I program that when I click on the element (of my RecyclerView) it executes an Intent with a putExtra to take me to another activity, the variable that contains my putExtra comes from the element that I clicked, but now I need to add a More variable that comes from the activity. The issue is that I don't know how to send it from the adapter.

this is my adapter.

package com.example.atipicoapp

import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.LinearLayout
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>
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {






    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()

        when(holder){

            is MyViewHolder -> {

                holder.bind(platoList[position])

            }

        }

    }

    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 platoTouch: LinearLayout = itemView.findViewById(R.id.platoTouch)

        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){

            platoTouch.setOnClickListener{


                intent.putExtra("id", platoName.text.toString())
                mActivity.startActivity(intent)
            }

        }


    }
}

And this is my Activity which contains my RecyclerView and the variable I want to send.

package com.example.atipicoapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_menu_atipico.*

class MenuAtipicoActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var platoArrayList: ArrayList<Plato>
    private lateinit var myAdapter: MyAdapter
    private lateinit var db: FirebaseFirestore

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_menu_atipico)

        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setHasFixedSize(true)

        platoArrayList = arrayListOf()

        myAdapter = MyAdapter(platoArrayList)

        recyclerView.adapter = myAdapter

        pedidoId = intent.extras?.getString("pedidoId") //This is the variable I need to send

        EventChangeListener()

        Setup()

    }

    private fun EventChangeListener() {


        db = FirebaseFirestore.getInstance()
        db.collection("Platos").addSnapshotListener(object : EventListener<QuerySnapshot> {
            override fun onEvent(
                value: QuerySnapshot?,
                error: FirebaseFirestoreException?
            ) {

                if (error != null) {

                    Log.e("Firestore Error", error.message.toString())
                    return

                }

                for (dc: DocumentChange in value?.documentChanges!!) {

                    if (dc.type == DocumentChange.Type.ADDED) {

                        platoArrayList.add(dc.document.toObject(Plato::class.java))

                    }

                }

                myAdapter.notifyDataSetChanged()

            }


        })


    }

    private fun Setup() {

        botonAceptar.setOnClickListener {

            val SlotIntent = Intent(this, SlotActivity::class.java).apply {


            }
            startActivity(SlotIntent)
        }

    }

}

How can I send the variable if the Intent is executed from the Adapter?

Or... If it is not recommended to send intent from my Adapter, how can I send them from the activity? Knowing that I have to carry a variable that is in the item of the RecyclerView.

Thanks for your help <3

  • My advice would be to avoid sending intents from the adapter altogether. It violates the single responsibility principle of OOP. It’s burying your top level navigation of your app down in an adapter. Your adapter’s responsibility should be solely to hook up data to UI. See my answer to your previous question for more details about how to do that. Trying to do it like this, where a higher level class (the Activity or Fragment) has to pass its functionality down into one of the classes that it controls so that class can reach back up and manipulate it...that's what leads to "spaghetti code". – Tenfour04 Feb 19 '22 at 23:34
  • I already updated my question. – Lucas Andres Escudero Feb 19 '22 at 23:43
  • Did you look at my answer on your previous question? It describes pretty clearly I think how to do this. – Tenfour04 Feb 19 '22 at 23:56

1 Answers1

1

Firstly, create a MyAdapter constructor where you pass arrayList as well as pedidoId like, your MyAdapter should be something like below:

MyAdapter.class

class MyAdapter(private val platoList : ArrayList<Plato>, val pedidoId:String
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
 ........
 .....
 ....
 
 //in your bind(..) method
   fun bind(plato: Plato){
     platoTouch.setOnClickListener{
       intent.putExtra("id", platoName.text.toString())
       intent.putExtra("pedidoId", pedidoId)
       mActivity.startActivity(intent)
     }
   }
}

And, in your MenuAtipicoActivity you need to do something like:

MenuAtipicoActivity

class MenuAtipicoActivity : AppCompatActivity() {
 ...............
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_menu_atipico)

    recyclerView = findViewById(R.id.recyclerView)
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.setHasFixedSize(true)

    platoArrayList = arrayListOf()
    pedidoId = intent.extras?.getString("pedidoId") //This is the variable I need to send
    myAdapter = MyAdapter(platoArrayList,pedidoId)
    recyclerView.adapter = myAdapter
    EventChangeListener()

    Setup()

  }
  ..........
  ........
 
}
Rudra Rokaya
  • 637
  • 1
  • 5
  • 9