ZOFTINO.COM

RecyclerView ItemDecoration

To make item’s separation visible or enhance the look and feel of items when items in RecyclerView are displayed on the screen, items in the list needs to be decorated.

RecyclerView allows you to plug-in decoration for items in RecyclerView. Itemdecoration is a separate component which needs to be defined and added to recycler view.

You can create itemdecoration object by extending RecyclerView ItemDecoration class. RecyclerView uses provided itemdecoration while items are laid out.

There are three methods in RecyclerView.ItemDecoration class, method getItemOffsets provides offset data, onDraw method draws decoration before items are drawn and onDrawOver method draws decoration after items are drawn.

ItemDecoration can be added to recycler view by calling addItemDecoration. Multiple itemdecorations can be added to recycler view; they are executed in the order added to recycler view.

In this post, I’ll show how to create RecyclerView ItemDecoration object for various recycler view layouts and orientations. If you want to know how to use recycler view, you can refer to recycler view example and recycler view and grid layout manager posts.

RecyclerView ItemDecoration Divider

Divider ItemDecoration draws divider separating two items in RecyclerView. It works for both horizontal and vertical orientations with LinearLayoutManager. Divider ItemDecoration draws a line between items using Paint.

You need to pass context, divider color and line width as parameter to the constructor of the item decoration. Divider ItemDecoration detects layout orientation automatically and draws horizontal or vertical divider depending upon layout orientation.

ItemDecoration Divider overrides method getItemOffsets to add space for divider, for horizontal orientation add inset to right and for vertical orientation add inset to bottom of item.

ItemDecoration Divider overrides method onDraw to draw divider to convas.

RecyclerView ItemDecoration Divider Code

 package com.zoftino.androidui;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class LinearDividerItemDecoration extends RecyclerView.ItemDecoration{
    private Paint paint;
    private Context context;
    private int dividerHeight;

    private int layoutOrientation = -1;

    public LinearDividerItemDecoration(Context ctx, int color, int dHeight){
        paint = new Paint();
        paint.setColor(color);
        paint.setStrokeWidth(dHeight);

        dividerHeight = dHeight;
        context = ctx;
    }
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        if(parent.getLayoutManager() instanceof LinearLayoutManager && layoutOrientation == -1){
            layoutOrientation = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        }

        if(layoutOrientation == LinearLayoutManager.HORIZONTAL){
            outRect.set(0, 0, dividerHeight, 0);
        }else{
            outRect.set(0, 0, 0, dividerHeight);
        }

    }
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);

        if(layoutOrientation == LinearLayoutManager.HORIZONTAL){
                horizontalDivider(c, parent);
        }else{
                verticalDivider(c, parent);
        }
    }
    private void horizontalDivider(Canvas c, RecyclerView parent){
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int itemCount = parent.getChildCount();
        for (int i = 0; i < itemCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            c.drawLine(left,top,left,bottom, paint);
        }
    }
    private void verticalDivider(Canvas c, RecyclerView parent){
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            c.drawLine(left,top,right,top, paint);
        }
    }
}
 

RecyclerView ItemDecoration Divider Output

Recyclerview ItemDecoration divider horizontal exampleRecyclerview ItemDecoration divider vertical example

RecyclerView ItemDecoration Item Border

Below item decoration draws border for each item in recycler view. Border item decoration also overrides getItemOffsets and onDraw, and uses paint to draw border around item. Below is the code.

 package com.zoftino.androidui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class BoundaryItemDecoration  extends RecyclerView.ItemDecoration{
    private Paint paint;
    private Context context;
    private int dividerHeight;

    private int layoutOrientation = -1;

    public BoundaryItemDecoration(Context ctx, int color, int dHeight){
        paint = new Paint();
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(dHeight);

        dividerHeight = dHeight;
        context = ctx;
    }
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        outRect.set(dividerHeight, dividerHeight, dividerHeight, dividerHeight);

    }
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if(parent.getLayoutManager() instanceof LinearLayoutManager && layoutOrientation == -1){
            layoutOrientation = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        }
        if(layoutOrientation == LinearLayoutManager.HORIZONTAL){
            horizontal(c, parent);
        }else{
            vertical(c, parent);
        }
    }
    private void horizontal(Canvas c, RecyclerView parent){
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int itemCount = parent.getChildCount();
        for (int i = 0; i < itemCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = child.getLeft() + dividerHeight;
            c.drawRect(left,top,right,bottom, paint);
        }
    }
    private void vertical(Canvas c, RecyclerView parent){
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = child.getTop() + dividerHeight;
            c.drawRect(left,top,right,bottom, paint);
        }
    }
}
 

RecyclerView ItemDecoration Item Border Output

Recyclerview ItemDecoration item border

RecyclerView ItemDecoration for GridLayoutManager

You need to adjust item decorations provided in this post to suit your item layout.

 private void horizontalGrid(Canvas c, RecyclerView parent){
    final int itemCount = parent.getChildCount();
    for (int i = 0; i < itemCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int left = child.getRight() + params.rightMargin;
        final int right = child.getLeft() + dividerHeight;
        c.drawRect(left,child.getTop()+dividerHeight,right,child.getBottom()+dividerHeight, paint);
    }
}
 
Recyclerview ItemDecoration GridLayoutManager