Up until now I used the Adapter's onBindViewHolder
to set an alternating background based on the item's Adapter-Position.
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setBackgroundResource(position % 2 == 0 ?
R.color.list_item_background_alternating : R.color.list_item_background);
...
}
However, this is getting more an more complicated when doing more than just showing a list.
For example: When I remove an item and call notifyItemRemoved(index);
the RecyclerView
does a nice animation and the item view is gone. However, the view which replaces the removed one doesn't get bound again (for obvious & good reasons) and therefore keeps it's old background. This leads to inconsistencies with the layout and looks ugly. When I call notifyDataSetChanged();
the backgrounds are all correct, but I lose the animation.
I have a similar problem when I'm using SortedList
(with a SortedListAdapterCallback
). Since the sorting seems to take place after the views are bound the backgrounds are in shambles.
What would be a proper/consistent way to implement such behaviour?
Alright, while I was writing up my question I wanted to try one thing out which I thought wouldn't work - however, it did.
I created an ItemDecoration
and used it's getItemOffset();
to set the view's background:
public class BackgroundItemDecoration extends RecyclerView.ItemDecoration {
private final int mOddBackground;
private final int mEvenBackground;
public BackgroundItemDecoration(@DrawableRes int oddBackground, @DrawableRes int evenBackground) {
mOddBackground = oddBackground;
mEvenBackground = evenBackground;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
view.setBackgroundResource(position % 2 == 0 ? mEvenBackground : mOddBackground);
}
}
I feel a bit guilty though, that I'm piggy-bagging on getItemOffsets()
.
Does anyone have a cleaner/better solution?
This is my solution The itemView refers to the View from the Layout inflater in the onCreateViewHolder.
public void onBindViewHolder(MyViewHolder holder, int position){
//alternate row color
if(position % 2==0)
holder.itemView.setBackgroundColor(Color.YELLOW);
else
holder.itemView.setBackgroundColor(Color.LTGRAY);
)
That is all you need. Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With