1

I have question, I want to make an item clicked in recyclerview, in adapter class I used the below method for define item clicked:

var onItemClick: ((ResponseGetDate) -> Unit)? = null

ResponseGetDate is the data class

also in the viewHolder (inner class) I used above variable for defining item clicked:

      holder.itemView.setOnClickListener {
        onItemClick?.invoke(itemDate)

    }

itemData is an item of ResponseGetDate class

Now, in the main activity or fragment when I build an instance from the adapter class, I can click on each item. see the code below:

      adapterGetDate.onItemClick = { dateItem ->

      }

The question is: if I want to click on each item, the item must be selected. and if I click on the another item, previous item must be deselected and the new one be selected. How can I do this?

hassan bazai
  • 424
  • 6
  • 9

1 Answers1

1

Single item selection can be maintained in RecyclerView by

  • Two variables to be kept updated when an item is selected
  • The first variable maintains the currently selected position
  • The second variable maintains the last selected position
  • Two different background drawable for the selected and unselected items
  • Two methods in ViewHolder Class to change the background of items

Background drawable For the item selected in my example:

Drawable name: bg_capsule_selected

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners
     android:radius="300dp" />

    <stroke
        android:width="1dp"
        android:color="@color/white" />

    <solid android:color="@color/colorOffGreen" />
</shape>

For the item unselected

Drawable name: bg_capsule_unselected

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
     android:radius="300dp" />
    <stroke
        android:width="1dp"
        android:color="#11B8B7BA" />
    <solid android:color="#F3F3F4" />
</shape>

Variables

Two variables to be initialized in your Adapter Class

var selectedItemPos = -1
var lastItemSelectedPos = -1

Separate methods in the ViewHolder Class for changing the background of the items when selected and unselected

fun defaultBg() {
    binding.tvCurrencyName.background = context.getDrawable(R.drawable.bg_capsule_unselected)
}

fun selectedBg() {
    binding.tvCurrencyName.background = context.getDrawable(R.drawable.bg_capsule_selected)
}

Logic The logic is to update the variables and calling the notifyItemChange(position) which would then call the method onBindViewHolder(holder: ViewHolder, position: Int) for this to happen we have to initialize the click listener for each of the itemViews and update the variables accordingly with the adapter position and call notifyItemChange() method with passing the item position to change

init {
    itemView.setOnClickListener {
        selectedItemPos = adapterPosition
        if(lastItemSelectedPos == -1)
            lastItemSelectedPos = selectedItemPos
        else {
            notifyItemChanged(lastItemSelectedPos)
            lastItemSelectedPos = selectedItemPos
        }
        notifyItemChanged(selectedItemPos)
       onItemClick?.invoke(itemDate) // here you can keep the callback
    }
}

this code is written inside the ViewHolder Class as an init block Since we have set click listeners for every itemView and then when we call notifyItemChange() method would call onBindViewHolder() method and in this method, we would check for the position and change their background with the help of two methods written inside ViewHolder Class like this

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    if(position == selectedItemPos)
        holder.selectedBg()
    else
        holder.defaultBg()
    holder.bindItems(adapterList[position])
}
SagaRock101
  • 129
  • 1
  • 7