'How to trigger other CardView element in recyclerview than clicked?

I have a method in adapter using recyclerview I basically display some elements of cardViews.

How to trigger method on other element where usually I use

cardView.setOnClickListener {
// MY action on specific} cardView element

for example when I click third element, <MY ACTION> happens in second element? Inside cardView I can i.e use:

statusButtons.toggleVisibility(!statusButtons.isVisible)

but it will only work when I trigger actual element using method

cardView.setOnClickListener { }

I have found something similiar How to access all cardviews in a recyclerview, on item click of a particular cardview

but it is not directly related to my case, I need to make action on specific ID like

statusButtons.toggleVisibility(!statusButtons.isVisible) where I not have argument to change


Solution 1:[1]

You can use the RecyclerView.findViewHolderForLayoutPosition(position) function to get the ViewHolder at given position and call functions on that ViewHolder from the activity/fragment. The function returns null if no ViewHolder exists at given position

class YourAdapter(
    onCardClick: (Int) -> Unit
) {

    ...

    inner class YourViewHolder {
        fun bind() {
            cardView.setOnClickListener {
                onCardClick(adapterPosition)
            }
        }
      
        fun operateOnCard() {
            statusButtons.toggleVisibility(!statusButtons.isVisible)
        }
    }
}

class YourActivity {
    
    ...

    val adapter = YourAdapter { position ->
        val viewHolder = recyclerView.findViewHolderForLayoutPosition(position - 1) // Or whatever position you want
        (viewHolder as? YourViewHolder)?.operateOnCard()
    }
}

Edit: If you need item.id in the activity for choosing the ViewHolder, you can pass the item as well from the lambda.

class YourAdapter(
    onCardClick: (Int, YourItem) -> Unit
) {
  ...
  onCardClick(adapterPosition, item)
  ...
}
class YourActivity {
    ...
    val adapter = YourAdapter { position, item ->
        // Here you have access to item as well
    }

You can update the onCardClick lambda depending upon whatever info you need to send from adapter to activity. Also, if you want to send the id to the operateOnCard function, you can also do that.

Solution 2:[2]

Solution: in Adapter

// define flowState
(...)
 val _stateFlow = MutableStateFlow(-1)
 val stateFlow = _stateFlow.asStateFlow()

// after every change of element
(...)
                CoroutineScope(Dispatchers.Main).launch {
                    stateFlow.collect { id ->
                        statusButtons.toggleVisibility(item.id == id)
                    }
                }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 chrisu.chrisu