RecyclerView.ItemDecoration is used to decorate the children of a RecyclerView. RecyclerView is a ViewGroup, with each of its children representing an item in a list. With ItemDecoration you can easily modify the appearance of these child views. Methods in RecyclerView.ItemDecoration class are

  • getItemOffsets() : Provides offset data
  • onDraw() : Draws decoration before items are drawn
  • onDrawOver() : Draws decoration after items are drawn

 

Divider ItemDecoration

Divider ItemDecoration draws divider separating two items in RecyclerView. It works for both horizontal and vertical orientations with LinearLayoutManager. 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.

// Set layout manager
recyclerView.setLayoutManager(layoutManager);

// Add the decoration to the recyclerView
DividerItemDecoration itemDecor = new DividerItemDecoration(getContext, HORIZONTAL);
recyclerView.addItemDecoration(itemDecor);

 

To add custom decoration, extend abstract class RecyclerView.ItemDecoration . To draw a separator between list elements, add some extra space on the bottom of the views to prevent overdrawing and finally draw a line on the bottom.

public class SeparatorDecoration extends RecyclerView.ItemDecoration{

  private Paint paint;
  private Context context;
  private int dividerHeight;

  private int layoutOrientation = -1;

  public SeparatorDecoration(Context ctx, int color, int dHeight){

    // Customization for the color and thickness of the separator
    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);

    // Setting an offset in each view.
    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);

    // Draw the separator
    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++) {

      // Get the child
      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);
    }
  }
}

 

To add item decorations in GridLayoutManager, modify the above code as follows

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);
  }
}

 

On Android, the view’s location is presented by top and left coordinates. Below image best describe getTop() and getBottom().