I've been trying to use the new RecyclerView widget for a couple of days now and thought I've managed to create a Horizontal and Grid layout and also overcome the fact that it lacks of a straightforward way of implementing a OnClickListener (I used GreenRobot's EventBus for this) , I'm still having a hard time selecting an item and preserving that state (style) throughout the recycling process.
This is the code I'm using for my adapter
public class ArticuloItemAdapter extends RecyclerView.Adapter<ArticuloItemAdapter.ItemHolder> { private ArrayList<ArticuloObject> mItems; private LayoutInflater mLayoutInflater; private int mSize; private int mSelectedPosition; private RecyclerView mRecyclerView; public ArticuloItemAdapter(Context context, RecyclerView rv, ArrayList<ArticuloObject> articulos) { mLayoutInflater = LayoutInflater.from(context); mItems=articulos ; mSize = context.getResources() .getDimensionPixelSize(R.dimen.icon); mSelectedPosition = -1; mRecyclerView = rv; } @Override public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = mLayoutInflater.inflate(R.layout.gallery_recycler_row, parent, false); return new ItemHolder(itemView, this); } @Override public void onBindViewHolder(ItemHolder holder, int position) { Ion.with(holder.getPicImageView()) .placeholder(R.drawable.owner_placeholder) .resize(mSize, mSize) .centerCrop() .error(R.drawable.owner_error) .load(mItems.get(position).getUrl()); //Update the views as they got recycled if (mSelectedPosition != position) { holder.getPicImageView().setBackgroundColor(Color.TRANSPARENT); } else { holder.getPicImageView().setBackgroundColor(Color.CYAN); } } @Override public int getItemCount() { return mItems.size(); } public int getSelectedPosition() { return mSelectedPosition; } public void setSelectedPosition(int mSelectedPosition) { this.mSelectedPosition = mSelectedPosition; } public RecyclerView getRecyclerView() { return mRecyclerView; } /* Required implementation of ViewHolder to wrap item view */ public class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ArticuloItemAdapter mParent; private ImageView mPicImageView; public ItemHolder(View itemView, ArticuloItemAdapter parent) { super(itemView); itemView.setOnClickListener(this); mParent = parent; mPicImageView = (ImageView) itemView.findViewById(R.id.picture_image_view); } public ImageView getPicImageView() { return mPicImageView; } @Override public void onClick(View v) { EventBus.getDefault().post(new OnArticuloCartaClickEvent(this, getPosition())); setItemActivated(v); } public void setItemActivated(View v) { //Check position of previous selected item. The first time an item is selected, the previous position will be -1 if (mParent.getSelectedPosition() >= 0) { ItemHolder row = (ItemHolder) mParent.getRecyclerView().findViewHolderForPosition(mParent.getSelectedPosition()); if (row != null) { row.getPicImageView().setBackgroundColor(Color.TRANSPARENT); } } mParent.setSelectedPosition(getPosition()); v.findViewById(R.id.picture_image_view).setBackgroundColor(Color.CYAN); } } } Now in the code shown above, all I'm doing to keep track of the selected item is the following:
I. In the onClick(View v) event:
- Whenever an item is clicked, I call the
setItemActivatedmethod - In the setItemActivated method, I check if the selectedPosition is greater than or equal to 0 ( the default is -1 when no item is selected).
- If the previous condition is true I try to get the
ViewHolderin that position and if that View is not null, I change the background colour of theImageViewback to it's original background colour (transparent) - Set the new value of mSelectedPosition to the current position using
getPosition() - Finally, change the background colour of the
ImageViewinside the currentViewHolderto a different colour (CYAN in this case)
II. In the onBindViewHolder(ItemHolder holder, int position) method:
If position of selected item (mSelectedPosition) is different from the position of the view being displayed, I change the background colour of the ImageView back to its default colour. Otherwise, I change the colour of the ImageView to the colour used to identify a selected item (CYAN).
All this works as long as the RecyclerView has a considerable number of item that it needs to start recycling the views. But if it doesn't, like in my case, I've noticed that findViewHolderForPosition always returns null, and as a result, I cannot change the colour of the previously selected item back to its default colour and so I ended up with more than one item selected.

And to make matters worse, as the RecyclerView doesn't have to recycle anything, the onBindViewHolder method never gets call and therefore I can't count on the code inside to adjust the colour of the items accordingly.
Please, I'd really appreciate if anyone could tell me what I'm doing wrong here or perhaps give some ideas. It's really frustrating not being able to do something as basic as selecting an item.
Thanks in advance.