Tech Blogging‎ > ‎

RecycleVew Adapter Show Wrong Data When Scrolling

posted Sep 3, 2017, 1:44 AM by Haris Hashim   [ updated Sep 3, 2017, 6:09 AM ]

Introduction

This is also a good code sample for RecyclerView within another RecyclerView. Get the code in GitHub!

When developing Android app using RecyclerView, common problem is to have wrong data displayed after scrolling. The reason is because RecyclerView reuse previous RecyclerView widget to show next data after scrolling. 

Quick Fix

This problem can be quite hard to debug. So a quick and dirty solution is to disable the reuse or recycling function. Of course, this is a temporary solution or a workaround until real issue is discovered and fixed.

How to do that? Just set the ViewHolder setIsRecyclable to false in onBindViewHolder. As per bellow code snippet:
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ContentItem content = values.get(position);
holder.txtName.setText(content.getName());
holder.txtHeader.setText(content.getDescription());
holder.txtFooter.setText("Footer text is here!");

holder.setIsRecyclable(false);

vAdapter = new VariantAdapter(content.getVariants());
vRecyclerView.setAdapter(vAdapter);
}

Fixing the Real Problem

It turns out the real problem is RecyclerView should be declared inside ViewHolder rather than in the Adapter class. As per bellow code snippet:
public class ViewHolder extends RecyclerView.ViewHolder {
// ... codes redacted

private RecyclerView variantRecyclerView;

public ViewHolder(View v) {
super(v);
// ... codes redacted
variantRecyclerView = (RecyclerView) v.findViewById(R.id.variant_recycler_view);
}
}

The rest of the code is in the Adapter onBindViewHolder as bellow snippet:

    @Override
public void onBindViewHolder(ViewHolder holder, final int position) {
// ... codes redacted
variantLayoutManager = new LinearLayoutManager(holder.view.getContext());
holder.variantRecyclerView.setLayoutManager(variantLayoutManager);
variantAdapter = new VariantAdapter(content.getVariants());
holder.variantRecyclerView.setAdapter(variantAdapter);
}

After implementing the above code, it is save to remove code that disable reuse/recycle function in previous section.

You can view and try the entire test code in GitHub. Master branch contains the fixed code while not-fixed branch is otherwise for testing and reproducing the error. 
Comments