Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: RecyclerView content messed up after scrolling [closed]

I'm using RecyclerView to display a list of marks, and each mark of the value is shown as a CardView. But some contents of the cards are lost after the scrolling the RecyclerView down and scrolling back, as shown in the two screenshots below. The contents in the red rectangle is lost after scrolling.

BEFORE THE SCROLLING; enter image description here

AFTER THE SCROLLING; enter image description here

I'm wondering whether or not it's a bug of RecyclerView and find no solution after Googling for it.

All views are invisible except the title, their visibilities are depends on the mark's value.

Does anyone know why this would happen?

like image 452
Swisyn Avatar asked Apr 17 '15 14:04

Swisyn


2 Answers

After battling with this same issue for about 24 hours, I found a solution that worked for me. The key was using the setIsRecyclable() method of RecyclerView.ViewHolder class.

Here is a section of my onBindViewHolder() code.

@Override public void onBindViewHolder(final MyViewHolder holder, int position) {     final DataSource dataSource = dataSourceList.get(position);      holder.setIsRecyclable(false);      holder.name.setText(dataSource.getName());     holder.active.setChecked(dataSource.getActive());      String logoStr = dataSource.getLogo();      //Logo     /**      * Do all the logo insertion stunts here      */     /**      * Register the changes to the Switch      */     holder.active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){             dataSource.setActive(isChecked);         }     }); } 
like image 161
aphoe Avatar answered Oct 14 '22 09:10

aphoe


onBindHolder() is called several times as recycler needs a view, unless there's a new one when view type is changed. So each time you set visibility in child views, other views states are also changing.

Whenever you scroll up and down, these views are getting re-drawn with wrong visibility options.

Solution :

You have a setValue method check values and set to view. If neccessary it calls another method "showView". You need to implement else statement (which is value is 0 or null) and hideView there...

void setValue(Object value, TextView textView, TableRow row, View seperator) {     if (value != null) {         if (!isEmpty(value.toString())) {             textView.setText(String.valueOf(value));             showViews(row, seperator);         }     } else         hideViews(row, seperator); }  private void showViews(TableRow row, View seperator) {     row.setVisibility(View.VISIBLE);     seperator.setVisibility(View.VISIBLE); }  private void hideViews(TableRow row, View seperator) {     row.setVisibility(View.INVISIBLE); // if there is a empty space change it with View.GONE     seperator.setVisibility(View.INVISIBLE); } 
like image 39
Emre Aktürk Avatar answered Oct 14 '22 09:10

Emre Aktürk