Universal RecyclerView split line extension

This universal split line is referenced from the blog: https://blog.csdn.net/pengkv/article/details/50538121 On his basis, added the left and right margins of the distance attribute.

The divider can define the width, height, distance to the left and right, color, etc. first, let's see the following effects:

In the project, the RecyclerViewDivider.java is imported, and then referenced. There are several constructors in it. You can choose the one with the most parameters. You can set the color, width and height, and the distance between the left and right boundaries

        mRecyclerView.addItemDecoration(new RecycleViewDivider(getApplicationContext(), LinearLayoutManager.VERTICAL, 20, 60, 60, getApplicationContext().getResources().getColor(R.color.colorAccent)));

Here are all the codes of this provider. The comments are detailed:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class RecycleViewDivider extends RecyclerView.ItemDecoration {

    private Paint mPaint;
    private Drawable mDivider;
    private int mDividerHeight = 2;//Split line height, 1px by default
    private int mOrientation;//Direction of list: LinearLayoutManager.VERTICAL or LinearLayoutManager.HORIZONTAL
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private int mOffsetLeft = 0;    //Divider off left boundary
    private int mOffsetRight = 0;   //Divider off right boundary

    /**
     * Default divider: 2px height, gray color
     *
     * @param context
     * @param orientation List direction
     */
    public RecycleViewDivider(Context context, int orientation) {
        if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
            throw new IllegalArgumentException("Please input correct parameters!");
        }
        mOrientation = orientation;

        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    /**
     * Custom divider
     *
     * @param context
     * @param orientation List direction
     * @param drawableId  Split line picture
     */
    public RecycleViewDivider(Context context, int orientation, int drawableId) {
        this(context, orientation);
        mDivider = ContextCompat.getDrawable(context, drawableId);
        mDividerHeight = mDivider.getIntrinsicHeight();
    }

    /**
     * Custom divider
     *
     * @param context
     * @param orientation   List direction
     * @param dividerHeight Split line height
     *@param offsetLeft    Distance between split lines left margin
     * @param offsetRight   Split line distance right margin
     * @param dividerColor  Split line color
     */
    public RecycleViewDivider(Context context, int orientation, int dividerHeight, int offsetLeft, int offsetRight, int dividerColor) {
        this(context, orientation);
        mDividerHeight = dividerHeight;
        mOffsetLeft = offsetLeft;
        mOffsetRight = offsetRight;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(dividerColor);
        mPaint.setStyle(Paint.Style.FILL);
    }


    //Get split line size
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            outRect.set(0, 0, 0, mDividerHeight);
        } else {
            outRect.set(0, 0, mDividerHeight, 0);
        }
    }

    //Draw split line
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    /**
     * The separator line when drawing a vertical list is horizontal
     * Each time the left is the same, the top changes according to the child, the right is the same, and the bottom also changes
     * @param canvas
     * @param parent
     */
    private void drawVertical(Canvas canvas, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + layoutParams.bottomMargin;
            final int bottom = top + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left + mOffsetLeft, top, right - mOffsetRight, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left + mOffsetLeft, top, right - mOffsetRight, bottom, mPaint);
            }
        }
    }

    /**
     * The separator line when drawing the horizontal list is vertical
     * l,r Change; t, b unchanged
     * @param canvas
     * @param parent
     */
    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + layoutParams.rightMargin;
            final int right = left + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }
}

Of course, there is also a simpler way to use shape resource files without writing java code, which is suitable for simple split lines. The effect is as follows:

But the bad thing is, can't adjust the distance between the left and right margins, or use the right posture?

usage method:

//Add custom divider
        DividerItemDecoration divider = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL);
        divider.setDrawable(ContextCompat.getDrawable(this,R.drawable.divider_mileage));
        mRecyclerView.addItemDecoration(divider);

For the customized split line file, in drawable / divider ﹣ mile.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:height="20dp" />

    <solid android:color="#30c2b1" />

<!-- Doesn't work?-->
    <padding
        android:left="64dp"
        android:bottom="64dp"
        android:right="64dp"
        android:top="64dp" />

</shape>

Address of the whole project above: https://github.com/buder-cp/base_component_learn/tree/master/self_divider

Tags: Android Java xml Attribute

Posted on Sun, 05 Jan 2020 10:58:30 -0800 by wompgx