kenruizinoue
kenruizinoue

Reputation: 117

Android: RecyclerView's ImageView get Recycled at Scrolling

In my app I have a RecyclerView. Each item of the RecyclerView contains ImageView that represents bookmarked items.

I implemented a logic that checks for item state for toggling the ImageView's content (bookmarked state) at onBindViewHolder() method inside my custom adapter.

The problem I have is that when I scroll the view, I get recycled ImageView's asset although my logic is implemented at onBindViewHolder().

I already try these solutions here but no help:

Everyone said that you must implement logic inside the onBindViewHolder() method and make the logic dependent on the data model, but I already did that.

Here is my RecyclerAdapter.java code:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.BasicViewHolder> {


Context mContext;
List<DataModel> mDataModels;

public RecyclerAdapter(Context context, List<DataModel> dataModels) {
    mContext = context;
    mDataModels = dataModels;
}

@Override
public BasicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    int layoutIdForListItem = R.layout.item_layout;
    LayoutInflater inflater = LayoutInflater.from(context);
    boolean shouldAttachToParentImmediately = false;

    View view = inflater.inflate(layoutIdForListItem, parent, shouldAttachToParentImmediately);

    BasicViewHolder viewHolder = new BasicViewHolder(view);

    return viewHolder;
}

@Override
public void onBindViewHolder(BasicViewHolder holder, int position) {
    holder.bind(position);
}

@Override
public int getItemCount() {
    return mDataModels.size();
}

public class BasicViewHolder extends RecyclerView.ViewHolder {

    public final TextView titleTextView;
    public final ImageView bookmarkImageView;

    public BasicViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        titleTextView = itemView.findViewById(R.id.textView);
        bookmarkImageView = itemView.findViewById(R.id.imageView);
    }

    void bind(int listIndex) {
        titleTextView.setText(mDataModels.get(listIndex).getTitle());

        //I think here is where the problem is being caused
        if(mDataModels.get(listIndex).isSelected()) bookmarkImageView.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_bookmark));
    }
}
}

DataModelList only indicates to change ImageView of item at position 1

Nevertheless other items get the same ImageView when scrolling

I hope you guys can help me, thanks for your time.

Upvotes: 0

Views: 887

Answers (1)

Ben P.
Ben P.

Reputation: 54204

The problem with your code is that you only update bookmarkImageView when the item being bound is selected. Because of the way view recycling works, it is important to make sure to always update each view. In your case, that means showing a bookmark when the item is selected, and hiding the bookmark when the item is not selected.

Try something like this:

if (mDataModels.get(listIndex).isSelected()) {
    bookmarkImageView.setImageResource(R.drawable.ic_bookmark);
} else {
    bookmarkImageView.setImageDrawable(null);
}

Upvotes: 1

Related Questions