RecycleView ItemDecoration绘制分割线

支持绘制网格布局和瀑布流的网格线

/**
 * Created by hml on 2019/5/15
 */
public class GridDivider extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;
    private Paint mPaint;
    private int mDividerHeight = 2;

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

    /** * 自定义分割线
     *
     * @param context
     * @param drawableId 分割线图片
     */
    public GridDivider(Context context, int drawableId) {
        mDivider = ContextCompat.getDrawable(context, drawableId);
        mDividerHeight = mDivider.getIntrinsicHeight();
    }

    /** * 自定义分割线
     *
     * @param context
     * @param dividerHeight 分割线高度
     * @param dividerColor  分割线颜色
     */
    public GridDivider(Context context, int dividerHeight, int dividerColor) {
        mDividerHeight = dividerHeight;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(context.getResources().getColor(dividerColor));
        mPaint.setStyle(Paint.Style.FILL);
    }

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

    private int getSpanCount(RecyclerView parent) {
        // 列数
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
        }
        return spanCount;
    }

    /**
     * 绘制水平线
     * @param c
     * @param parent
     */
    public void drawHorizontal(Canvas c, RecyclerView parent) { 
        int spanCount  = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        boolean isLastRow;
        boolean isLastColum;
        int left;
        int right;
        int top;
        int bottom;
        for (int i = 0; i < childCount; i++) {
            isLastRow = isLastRaw(parent, i, spanCount, childCount);
            isLastColum = isLastColum(parent, i, spanCount, childCount);
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            left   = child.getLeft() - params.leftMargin;
            //是最后一列则最右边 是子view的最右边,若不是最后一列,则最右是子view的最右边+mDividerHeight
            right  = child.getRight()  + params.rightMargin + (isLastColum ? 0 : mDividerHeight);
            top    = child.getBottom() + params.bottomMargin;
            bottom = top + (isLastRow ? 0 : mDividerHeight);//若是最后一行则,不绘制。bottom = top,绘制的线看不见

            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

            if (mPaint != null) {
                c.drawRect(left, top, right, bottom, mPaint);
            }
        } 
    }

    /**
     * 绘制垂直线
     * @param c
     * @param parent
     */
    public void drawVertical(Canvas c, RecyclerView parent) { 
        int spanCount  = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        boolean isLastColum;
        int left;
        int right;
        int top;
        int bottom;
        for (int i = 0; i < childCount; i++) {
            isLastColum = isLastColum(parent, i, spanCount, childCount);
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            left   = child.getRight()  + params.rightMargin;
            //若是最后一列则,不绘制。right = left,绘制的线看不见
            right  = left + (isLastColum ? 0 : mDividerHeight);
            top    = child.getTop() - params.topMargin;
            bottom = child.getBottom() + params.bottomMargin;

            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

            if (mPaint != null) {
                c.drawRect(left, top, right, bottom, mPaint);
            }
        } 
    }

    /**
     * 判断是否是最后一列
     * @param parent
     * @param pos
     * @param spanCount
     * @param childCount
     * @return
     */
    private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            if ((pos + 1) % spanCount == 0) {
                // 如果是最后一列,则不需要绘制右边
                return true;
            }
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                if ((pos + 1) % spanCount == 0) {
                    // 如果是最后一列,则不需要绘制右边
                    return true;
                }
            } else {
                childCount = childCount - childCount % spanCount;
                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
                    return true;
            }
        }
        return false;
    }

    /**
     * 判断是否是最后一行
     * @param parent
     * @param pos
     * @param spanCount
     * @param childCount
     * @return
     */
    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            childCount = childCount - childCount % spanCount;
            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
                return true;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
            // StaggeredGridLayoutManager 且纵向滚动
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;
                // 如果是最后一行,则不需要绘制底部
                if (pos >= childCount)
                    return true;
            } else {
                // StaggeredGridLayoutManager 且横向滚动
                // 如果是最后一行,则不需要绘制底部
                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { 
        int spanCount  = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        boolean isLastRow = isLastRaw(parent, itemPosition, spanCount, childCount);
        boolean isLastColum = isLastColum(parent, itemPosition, spanCount, childCount);
        if (isLastRow && isLastColum) {
            // 如果是最后一行,而且是最后一列 什么都不做
            outRect.set(0, 0, 0, 0);
        } else if (isLastRow) {
            // 如果是最后一行,则不需要绘制底部,
            outRect.set(0, 0,mDividerHeight, 0);
        }else if (isLastColum){
            // 如果是最后一列,则不需要绘制右侧,
            outRect.set(0, 0,0, mDividerHeight);
        }else{
            outRect.set(0, 0,mDividerHeight, mDividerHeight);
        } 

    }
}

你可能感兴趣的:(Android)