user1234 user1234 - 1 year ago 57
Android Question

Can't get RecyclerView.Adapter to Properly Display

I followed this example here:

What's Happening:

The list (RecyclerView) is mixing up the data when I scroll. I.e. when I scroll back up after scrolling down, some of the list items are repeated, not displaying proper content.

Here is my


// cardsData is a List of MyCardItem (MyCardItem is just a holder of information,
// such as an id, String title, String summary, and other info to display on a card
public void onBindViewHolder(ViewHolder viewHolder, int position)
// Update view here
if (!cardsData.isEmpty())
viewHolder.updateDisplay(cardsData.get(position), activity, position);

Here is my
method found inside the ViewHolder class:

// Set ID
if (item.getID() != null)

// Set Title
if (item.getTitle() != null)

// Set Summary
if (item.getSummary() != null)

// Image
if (item.hasImage())
// Display image here

I believe it has something to do with the fact that sometimes the data is null, so I choose not to display it. Not all items (cards) will have an image to display, so this is why I check for if the item is supposed to have an image. If it does, then I do some fancy code to show an image (and making the other views
so I can only show that image, etc.).

While debugging, I forced all cards to display their id and position in the title. I can confirm that all ids and positions are in their proper places. When I force (removing the if check for id, title, and summary) the id, title, and summary to display, even if null, that content becomes unaffected. However, this does not solve my image situation (won't always have an image). I'll then have some images taking up the place for a certain id/position, where it should not (i.e. instead of displaying the summary text, it shows an image that isn't supposed to be there).

Any input as to why this is happening in my RecyclerView?

Answer Source

RecyclerView, just the same as ListView and GridView, reuses views whenever possible. That means while you scroll, views that fall off the top are used for the views on the bottom, etc. This greatly improves the memory efficiency and scroll performance. This means if you don't reset all of the state on a new item, you'll see state left over from the last time this view was used.

Instead, you should always reset all the of the state:

if (item.getID() != null) {
} else {
// etc...

Also, there shouldn't be any situations where you need to check for cardsData.isEmpty() - instead, whenever you update cardsData, you should be calling the appropriate notifyXXX method (such as notifyItemInserted() or in the worse case notifyDataSetChanged()) which will automatically refresh the list appropriately.