How to get arraylist from recyclerview adapter in android kotlin



I have recyclerView which is having multiple items. Every item is holding a checkbox to select that item. I want to get the selected item in another ArrayList and pass it to my MainActivity. On accept click I called getselecteditem() but getselecteditem() function always returns null. Here is my adapter code.

class orderAdapter(val items: List<Orders>, val context: Context) :

    RecyclerView.Adapter<ViewHolder>() {
    var selectedItems: ArrayList<String> = ArrayList()
    var selectedList: ArrayList<String> = ArrayList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(context).inflate(
                R.layout.order_queue_item,
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        holder.tvQuantity?.text = "Quantity: ${items.get(position).totalCount}"
        holder.tvOrderId?.text = "Order No. : ${items.get(position).orderNumber}"
        holder.tvSum?.text = "Sum: ${items.get(position).totalPrice}"

        /*  holder.cbSelectOrder?.setOnClickListener(object : View.OnClickListener{
              override fun onClick(v: View?) {
                 selectedItems.add(items.get(position))
                  Log.e("selected"," "+selectedItems.size)
              }
          })*/

        holder.cbSelectOrder.setOnCheckedChangeListener { buttonView, isChecked ->
            if (isChecked) {
                selectedList.add(items.get(position).id)
                Log.e("selected", "items " + items.get(position).id)
                Log.e("selected", "selected " + selectedList.size)
                Log.e("selected", "selected " + selectedList.toString())
                //var size = selectedItems.size
                //  selectedList.addAll(selectedItems)
                notifyDataSetChanged()
            } else if(!isChecked) {
                selectedList.remove(items.get(position).id)
                Log.e("selected", "items " + items.get(position).id)
                Log.e("selected", "selected " + selectedList.size)
                Log.e("selected", "selected " + selectedList.toString())
                notifyDataSetChanged()
            }

            notifyDataSetChanged()
        }

        holder.btnView?.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {
                val intent = Intent(context, ReviewOrderActivity::class.java)
                intent.putExtra("orderId", items.get(position).id.toString())
                context.startActivity(intent) // put context infront

            }
        })

    }

    fun getSelected(): ArrayList<String> {

        Log.e("selected", "selectedlist " + selectedList.size)
        Log.e("selected", "selectedlist " + selectedList.toString())

        return selectedList
    }

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


}


class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    // Holds the TextView that will add each animal to
    val tvQuantity = view.findViewById<TextView>(R.id.tv_quantity)
    val tvOrderId = view.findViewById<TextView>(R.id.tv_order_id)
    val tvSum = view.findViewById<TextView>(R.id.tv_sum)
    val btnView = view.findViewById<Button>(R.id.btn_view)
    val cbSelectOrder = view.findViewById<CheckBox>(R.id.cb_button)
}

My MainActivity layout

Answer

  1. You need a callback which lets to fetch selected order and update list on every selected or un-select order
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    
    ....
    
    public interface Listener {
        fun getSelectedOrderList(list : ArrayList<String>);
    }
}
  1. orderAdapter constructor will have listener instance which will update selected list in main activity.
class orderAdapter(val items: List<Orders>, val context: Context, private val listener: ViewHolder.Listener)
  1. In MainActivity recyclerview listener will get list.
recyclerView.adapter = orderAdapter(getOrderList(), this, object : ViewHolder.Listener {
   override fun getSelectedOrderList(list: ArrayList<String>) {
       Log.d(TAG, "Selected order List : $list")
   }
})

orderAdapter class

class orderAdapter(val items: List<Orders>, val context: Context, private val listener: ViewHolder.Listener) :

    RecyclerView.Adapter<ViewHolder>() {
    var selectedItems: ArrayList<String> = ArrayList()
    var selectedList: ArrayList<String> = ArrayList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.order_queue_item, parent, false)
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        holder.tvQuantity.text = "Quantity: ${items.get(position).totalCount}"
        holder.tvOrderId?.text = "Order No. : ${items.get(position).orderNumber}"
        holder.tvSum?.text = "Sum: ${items.get(position).totalPrice}"
        holder.cbSelectOrder.setOnCheckedChangeListener { buttonView, isChecked ->

            if (isChecked) {
                selectedList.add(items.get(position).id)
                notifyDataSetChanged()
            } else if (!isChecked) {
                selectedList.remove(items.get(position).id)
                notifyDataSetChanged()
            }

            listener.getSelectedOrderList(selectedList)
            notifyDataSetChanged()
        }

        holder.btnView.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {
                Toast.makeText(context, "View Button Clicked", Toast.LENGTH_SHORT).show()
            }
        })

    }

    fun getSelected(): ArrayList<String> {
        return selectedList
    }

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



}


class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    // Holds the TextView that will add each animal to
    val tvQuantity = view.findViewById<TextView>(R.id.tv_quantity)
    val tvOrderId = view.findViewById<TextView>(R.id.tv_order_id)
    val tvSum = view.findViewById<TextView>(R.id.tv_sum)
    val btnView = view.findViewById<Button>(R.id.btn_view)
    val cbSelectOrder = view.findViewById<CheckBox>(R.id.cb_button)

    public interface Listener {
        fun getSelectedOrderList(list : ArrayList<String>);
    }
}



Source: stackoverflow