Search code examples
kotlinandroid-recyclerviewandroid-adapterandroid-databinding

Change the color of the Recycler view item and return to the original state in kotlin


I have a Recycler view to display a custom calendar and everything works fine My problem is: when I click on one item, the color of the item changes, but when I click on another item, the previous item does not return to default.

my code :

class CalendarAdapter(val clickListener: (CalendarModel) -> Unit) :
    ListAdapter<CalendarModel, CalendarAdapter.CalendarViewHolder>(CalendarDiffUtils()) {
private var select = -1

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CalendarViewHolder {
    val binding =
        CalendarItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    return CalendarViewHolder(binding, binding.root)
}

override fun onBindViewHolder(holder: CalendarViewHolder, position: Int) {
    holder.onBind(getItem(position))


}

override fun getItemViewType(position: Int): Int {
    return position
}


inner class CalendarViewHolder(
    private val binding: CalendarItemBinding,
    containerView: View
) :
    RecyclerView.ViewHolder(containerView) {


    fun onBind(dateModel: CalendarModel) {
        with(dateModel) {
            with(binding) {
                //Show empty days.
                txtIranianDate.isVisible = iranianDay != EMPTY_DATE
                txtGregorianDate.isVisible = iranianDay != EMPTY_DATE
                if (iranianDay == EMPTY_DATE) {
                    return
                }


                //Click
                itemView.setOnClickListener {
                    clickListener(dateModel)


                    select = adapterPosition                // <== select:Int = -1
                    //Change color With click
                    if (select == adapterPosition){         // <== Here I want change color.
                        cardDays.setCardBackgroundColor(
                            ContextCompat.getColor(
                                itemView.context,
                                R.color.blue
                            )
                        )
                    }else{                                  // <== back to the default color.
                        cardDays.setCardBackgroundColor(
                            ContextCompat.getColor(
                                itemView.context,
                                R.color.white
                            )
                        )
                    }

I have removed the additional codes related to the DiffUtils classes.


Solution

  • I found the solution to this issue and from what I thought was very simple, the way was that after clicking, we put the position adapter in the private var select = -1 value and use notifyDataSetChanged() inside the click block and We will change the color of the item outside the click block, pay attention to the code :

    class CalendarAdapter(val clickListener: (CalendarModel) -> Unit) :
        ListAdapter<CalendarModel, CalendarAdapter.CalendarViewHolder>(CalendarDiffUtils()) {
        private lateinit var context: Context
        private var selectedItem = -1
    //-----
    other
    
    //-----
    
    inner class CalendarViewHolder(private val binding: CalendarItemBinding, containerView: View) :
        RecyclerView.ViewHolder(containerView) {
    
    
    
        fun onBind(dateModel: CalendarModel) {
            with(dateModel) {
                with(binding) {
                    txtIranianDate.isVisible = iranianDay != EMPTY_DATE
                    txtGregorianDate.isVisible = iranianDay != EMPTY_DATE
                    if (iranianDay == EMPTY_DATE) {
                        return
                    }
    
                    //Click
                    itemView.setOnClickListener {
                        clickListener(dateModel)
                        selectedItem = adapterPosition
                        notifyDataSetChanged()
                    }
    
                    //Change color item clicked <-- Do this operation outside the click block
                       if (selectedItem == adapterPosition) {
                        cardDays.setBackgroundResource(R.drawable.bg_click_item_calendar)
                    } else {
                        cardDays.setBackgroundResource(R.drawable.background_item_calendar)
                    }
    
                   //other-------
    }