0

There is a Recyclerview in my activity. it has always 10 items. Recyclerview's item has two buttons witch each one's click listener is defined in onBindViewHolder method of adapter class. after clicking any of the items's buttons it calls a callback method witch is implemented in activity's onCreate method. The callback method passes adapterPosition to activity an activity returns a long value witch I update button's text with that.
The problem is when I click the first item's button of the recyclerview, it updates the first and the last item's text. First I used position but then changed it to adapterPosition or layoutPosition, but it didn't worked. sometime the one before last item gets updated and sometimes the last one gets updated with the updating of the first item

activity's onCreate code

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_videocrop)

    var segmentAdapter = SegmentAdapter(10)
    var layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
    videoCropRecyclerView.adapter = segmentAdapter
    videoCropRecyclerView.layoutManager = layoutManager

    segmentAdapter.onSegmentSelectedListener = object : OnSegmentSelectedListener {
        override fun onSelectFrom(index: Int): Int? {
            return 12345
        }

        override fun onSelectTo(index: Int): Int? {
            return 54321
        }
    }
}


Adapter class code

class SegmentAdapter(var segments: Int) : RecyclerView.Adapter<SegmentAdapter.SegmentViewHolder>() {

    var onSegmentSelectedListener: OnSegmentSelectedListener? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SegmentViewHolder =
            SegmentViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.videocrop_segment_item, parent, false))

    override fun getItemCount(): Int = segments

    override fun onBindViewHolder(holder: SegmentViewHolder, position: Int) { 
        holder.from!!.setOnClickListener {
            holder.from!!.text = onSegmentSelectedListener!!.onSelectFrom(holder.adapterPosition)
        }
        holder.to!!.setOnClickListener {
            holder.to!!.text = onSegmentSelectedListener!!.onSelectTo(holder.adapterPosition)
        }
    }

    class SegmentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var from: Button? = null
        var to: Button? = null

        init {
            from = itemView.findViewById(R.id.videoCropSegmentItemFromButton)
            to = itemView.findViewById(R.id.videoCropSegmentItemToButton)
        }
    }
}


Callback Interface Code

interface OnSegmentSelectedListener {
    fun onSelectFrom(index:Int):Int?
    fun onSelectTo(index:Int):Int?
}


when I click the first item's button and its text becomes "0"
enter image description here


then I scroll down to the last item and I see the last item is also updated
enter image description here



I also checked this question but it wasn't helpful.


I would be very thankful if somebody helps me

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Reza
  • 845
  • 13
  • 18

1 Answers1

1

Your onBindViewHolder method is not handling recycled views. You need to set the text every time in onBindViewHolder based on the backing data, rather than just setting it in the click listener, because you may get an itemView re-used from a different item (in this case, the first item where you've changed the text).

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • thanks my friend, big time. I did what you said. Moved updates out of click listener and passed the data to adapter instead of returning it from callback method and it works like charm. – Reza Feb 08 '20 at 07:08
  • Glad it helped! Feel free to mark the answer as accepted to help others who might encounter the issue as well – Ryan M Feb 10 '20 at 18:57