Faybian
Faybian

Reputation: 393

How to reset RecyclerView Viewholder layout when scrolling

I'm using a Viewholder in my RecyclerView adapter, in which I'm dynamically creating ImageViews. However, when I scroll down and back up, the new images get displayed on top of the previous images. I understand that this is the concept of recycling but how can I reset/clear the Viewholder/layout so that old ImageViews do not appear on each recycled view?

public class RallyAdapter extends RecyclerView.Adapter<RallyAdapter.ViewHolder> {

public static class ViewHolder extends RecyclerView.ViewHolder{
    public TextView nameTextView;
    public TextView dateTextView;
    public TextView creatorTextView;
    public ImageButton thumbnail;
    public RelativeLayout relativeLayout;

    public ViewHolder(View itemView) {

        super(itemView);

        relativeLayout = (RelativeLayout) itemView.findViewById(R.id.view);
        nameTextView = (TextView) itemView.findViewById(R.id.name);
        dateTextView = (TextView) itemView.findViewById(R.id.date);
        thumbnail = (ImageButton) itemView.findViewById(R.id.imageButton);
        creatorTextView = (TextView) itemView.findViewById(R.id.creator_name);
    }
}

private ArrayList<Rally> mRallys;
private Context mContext;

public RallyAdapter(Context context, ArrayList<Rally> rallys) {
    this.mRallys = rallys;
    this.mContext = context;
}

// Usually involves inflating a layout from XML and returning the holder
@Override
public RallyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    // Inflate the custom layout
    View rallyView = inflater.inflate(R.layout.rally, parent, false);

    // Return a new holder instance
    ViewHolder viewHolder = new ViewHolder(rallyView);


    return viewHolder;
}

// Involves populating data into the item through holder
@Override
public void onBindViewHolder(RallyAdapter.ViewHolder viewHolder, final int position) {

    // Get the data model based on position
    final Rally rally = mRallys.get(position);

    // Set item views based on the data model
    TextView nameTV = viewHolder.nameTextView;

    nameTV.setText(rally.getName());

    TextView dateTV = viewHolder.dateTextView;

    dateTV.setText(rally.getStartDate());

    ImageButton imageButton = viewHolder.thumbnail;

    TextView creatorTV = viewHolder.creatorTextView;

    creatorTV.setText(rally.getCreator_name());

    Picasso.with(mContext).load(rally.getThumbnail()).fit().centerCrop().into(imageButton);

    List<String> image_urls = rally.getTransportationImgs();
    List<String> methods = rally.getTransportationStrs();
    ArrayList<ImageView> IMGS = new ArrayList<ImageView>();

    for (int i = 0; i < methods.size(); i++) {

        String method = methods.get(i);

        for (int j = 0; j < image_urls.size(); j++) {

            String img_url = image_urls.get(j);

            if (img_url.toLowerCase().contains(method.toLowerCase()) == true) {

                ImageView image = new ImageView(mContext);
                dateTV = viewHolder.dateTextView;
                imageButton = viewHolder.thumbnail;

                image.setId(generateViewId());

                IMGS.add(image);

                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

                if (IMGS.size() > 1) {

                    params.addRule(RelativeLayout.RIGHT_OF, IMGS.get(IMGS.size() - 1).getId());
                    params.addRule(RelativeLayout.ALIGN_TOP, IMGS.get(IMGS.size() - 1).getId());
                    params.addRule(RelativeLayout.END_OF, IMGS.get(IMGS.size() - 1).getId());
                } else {

                    params.addRule(RelativeLayout.RIGHT_OF, imageButton.getId());
                    params.addRule(RelativeLayout.BELOW, dateTV.getId());
                    params.addRule(RelativeLayout.END_OF, imageButton.getId());
                }

                params.height = 65;
                params.width = 65;

                image.setLayoutParams(params);

                viewHolder.relativeLayout.addView(image);

                //viewHolder.relativeLayout.addView(rallyLayout);

                Picasso.with(mContext).load(img_url).fit().centerCrop().into(image);
            }
        }
    }
}

Here's how the views look on load.

enter image description here

After scrolling around for a bit...

enter image description here

Upvotes: 1

Views: 10507

Answers (2)

Eric P&#246;hlsen
Eric P&#246;hlsen

Reputation: 1

As I just encountered a similar problem, if you set a lot of styling in onBindViewHolder() it maybe helpful to override onViewRecycled() as well to restore the view to its original condition ...

Upvotes: 0

tachyonflux
tachyonflux

Reputation: 20211

I think you need to have a LinearLayout hold your icons and clear it before your for loop:

viewHolder.linearLayout.removeAllViews();

Upvotes: 7

Related Questions