1

I have a list of contacts that is shown in recyclerview. After clicking on an item its view changes in the way I want to and if I click on another item the previous selected one returns back to its original state so, so far everything is good. However when I click on the item that is already clicked before and expanded nothing happens. Here is my code in onBindViewHolder

if(selectedPosition==position){
if(holder.itemView.contactsListOptionsMenu.isVisible){
    holder.itemView.contactsListOptionsMenu.visibility = View.GONE
    holder.itemView.contactsListCallBtn.visibility = View.GONE
    holder.itemView.contactsListDetailsBtn.visibility = View.GONE
    holder.itemView.contactFullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0,0,R.drawable.ic_arrow_down_24,0)
} else{
    holder.itemView.contactsListOptionsMenu.visibility = View.VISIBLE
    holder.itemView.contactsListCallBtn.visibility = View.VISIBLE
    holder.itemView.contactsListDetailsBtn.visibility = View.VISIBLE
    holder.itemView.contactFullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0,0,R.drawable.ic_arrow_up_24,0)
}

} else { if(holder.itemView.contactsListOptionsMenu.isVisible){

    holder.itemView.contactsListOptionsMenu.visibility = View.GONE
    holder.itemView.contactsListCallBtn.visibility = View.GONE
    holder.itemView.contactsListDetailsBtn.visibility = View.GONE
    holder.itemView.contactFullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0,0,R.drawable.ic_arrow_down_24,0)
}

}

what do I have to do in order to collapse the item that is already expanded when I click on it again and vice versa?

Tenesuzun
  • 93
  • 1
  • 9
  • when I follow what happens step by step in debugger. I have noticed in onClick after assigning position to selectedPosition I call notifyDataSetChanged() so while code goes through the items whenever the position becomes the index just before selectedPosition code enters the last if statement. Thus when both position and selectedPosition are same holder.itemView.contactsListOptionsMenu.isVisible this returns false where as it should return true – Tenesuzun Aug 11 '21 at 12:53

1 Answers1

0

it's not a good idea to use view visibility in logic. you should use selectedPosition variable to find the ViewHolder that is currently selected.

and on view holder click:

  • if the view holder is clicked for the first time, assign position to selectedPosition.

  • if the view holder is clicked before and it's clicked now again, assign -1 to selected Position.

  • call notifyDataSetChanged() to update UI.

you can do this in onBindViewHolder():

    holder.itemView.setOnClickListener {
        selectedPosition = if (position == selectedPosition) {
            -1
        } else {
            position
        }
        notifyDataSetChanged()
    }

    if (selectedPosition == position) {
        holder.itemView.contactsListOptionsMenu.visibility = View.VISIBLE
        holder.itemView.contactsListCallBtn.visibility = View.VISIBLE
        holder.itemView.contactsListDetailsBtn.visibility = View.VISIBLE
        holder.itemView.contactFullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_up_24, 0)
    } else {
        holder.itemView.contactsListOptionsMenu.visibility = View.GONE
        holder.itemView.contactsListCallBtn.visibility = View.GONE
        holder.itemView.contactsListDetailsBtn.visibility = View.GONE
        holder.itemView.contactFullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_down_24, 0)
    }
    
Iman Dolatkia
  • 186
  • 1
  • 7
  • 1
    Thanks a lot. I tried and it worked just as I wanted so thanks again but I wondered why did you say using view visibility in logic is not a good idea? Can you explain that for me please? – Tenesuzun Aug 12 '21 at 06:10
  • MVVM, MVP, MVC architectures provide ways to separate logic from UI, you can search it in google :) @Tenesuzun – Iman Dolatkia Aug 12 '21 at 19:11