Understanding RecycleView Decorations

RecycleViews are a common Android UI pattern for displaying multiple items. By overriding RecycleView decorators, you can enhance your UI by separating items into groups, highlighting differences and adding offsets to visually distinguish data. Read on for our developer Chao Shi’s description of how to customize and extend them!

ItemDecoration:

This is an abstract class that is used for decorating the items for the recycleView.

It’s description in source code is:

An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter’s data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.

The basic function is setting the margins to the four sides of the item as well as the divider to each item.

There are a total of 6 abstract methods to ItemDecoration, 3 of them have been deprecated, so we only need to learn the following 3 below:

1. getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) → used for setting margins

2. onDraw(Canvas c, RecyclerView parent, State state) → used for draw decoration

3. onDrawOver(Canvas c, RecyclerView parent, State state) → used for drawing the mask

getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)

For this method, it is mainly used to set the offset around the item.

Rect outRect: we can simply understand that it is used as the padding for the item.

View view: childView: it is the item itself. It’s the root View of the item rather than the controller view inside the item.

RecyclerView parent: is the recycleView itself.

RecyclerView.State state: RecyclerView’s statement. The comment in the source code for State is →“Contains useful information about the current RecyclerView state like target scroll position or view focus. State object can also keep arbitrary data, identified by resource ids.”

Tip 1: state.getItemCount() is not 100% equal to getAdapter.getItemCount(). If you want to make a calculation for the position, you should use state.getItemCount.

Tip 2: The return value of RecycleView.getChildCount() is not the total number of items for the adapter. It’s actually the number of total visible items.

When would getItemOffsets method get called?

The only place this method was getting called is in getItemDecorInsetsForChild(View child), which would be called by RecyclerView’s measureChild(View child, int widthUsed, int heightUsed).

In fact, the outRect value from getItemOffsets was included into the padding for each RecycleView’s itemView.

onDraw(Canvas c, RecyclerView parent, State state)

This method is used for drawing the divider, which is underneath the item. If we override the method onDraw and onDrawOver, it would have some influence on drawing items for a RecycleView.

onDrawOver(Canvas c, RecyclerView parent, State state)

This method was called after onDraw method, and it is drawing on the top layer. It would get called every time when the recycleView is scrolling.

We should notice every time it’s called, the previous drawing would be cleared → only the latest drawing would be saved. The mask would only have at most one state.

The Order of Drawing

mItemDecoration.onDraw()--> item.onDraw()--> mItemDecoration.onDrawOver()

The onDraw method can set the draw range for the divider, the range can even be bigger than getItemOffsets’ range.


As ever, QuarkWorks is available to help with any software application project — web, mobile, and more! If you are interested in our services you can check out our website. We would love to answer any questions you have! Just reach out to us on our Twitter, Facebook, or LinkedIn.