package com.github.jdsjlzx.ItemDecoration; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.support.annotation.DimenRes; import android.support.v4.content.ContextCompat; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.LayoutManager; import android.support.v7.widget.RecyclerView.State; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.TypedValue; import android.view.View; import com.github.jdsjlzx.recyclerview.LRecyclerView; import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter; public class GridItemDecoration extends RecyclerView.ItemDecoration { private int verticalSpace; private int horizontalSpace; private Paint mPaint; public GridItemDecoration(int horizontalSpace, int verticalSpace, int colour) { this.horizontalSpace = horizontalSpace; this.verticalSpace = verticalSpace; mPaint = new Paint(); mPaint.setColor(colour); } @Override public void onDrawOver(Canvas c, RecyclerView parent, State state) { drawHorizontal(c, parent); drawVertical(c, parent); } private int getSpanCount(RecyclerView parent) { // 列数 int spanCount = -1; LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount(); } return spanCount; } public void drawHorizontal(Canvas c, RecyclerView parent) { int childCount = parent.getChildCount(); LRecyclerView recyclerView = (LRecyclerView) parent; LRecyclerViewAdapter adapter = (LRecyclerViewAdapter) parent.getAdapter(); for (int i = 0; i < childCount; i++) { if ((recyclerView.isOnTop() && (adapter.isHeader(i) || adapter.isRefreshHeader(i))) || adapter.isFooter(i)) { c.drawRect(0, 0, 0, 0, mPaint); } else { final View child = parent.getChildAt(i); final int top = child.getBottom(); final int bottom = top + verticalSpace; int left = child.getLeft(); int right = child.getRight(); c.drawRect(left, top, right, bottom, mPaint); } } } public void drawVertical(Canvas c, RecyclerView parent) { final int childCount = parent.getChildCount(); LRecyclerView recyclerView = (LRecyclerView) parent; LRecyclerViewAdapter adapter = (LRecyclerViewAdapter) parent.getAdapter(); for (int i = 0; i < childCount; i++) { if ((recyclerView.isOnTop() && (adapter.isHeader(i) || adapter.isRefreshHeader(i))) || adapter.isFooter(i)) { c.drawRect(0, 0, 0, 0, mPaint); } else { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int top = child.getTop(); final int bottom = child.getBottom() + verticalSpace; final int left = child.getRight() + params.rightMargin; final int right = left + horizontalSpace; c.drawRect(left, top, right, bottom, mPaint); } } } /** * @param parent RecyclerView * @param pos 当前item的位置 * @param spanCount 每行显示的item个数 * @param childCount child个数 */ private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) { LayoutManager layoutManager = parent.getLayoutManager(); LRecyclerViewAdapter adapter = (LRecyclerViewAdapter) parent.getAdapter(); if (layoutManager instanceof GridLayoutManager) { int leftCount = childCount - childCount % spanCount;//3 //leftCount:若childCount能被span整除为childCount否则为去掉最后一行的item总数 if ((pos - adapter.getHeaderViews().size() + 1) > leftCount) { return true; } } return false; } private boolean isLastColumn(RecyclerView parent, int pos, int spanCount) { LayoutManager layoutManager = parent.getLayoutManager(); LRecyclerViewAdapter adapter = (LRecyclerViewAdapter) parent.getAdapter(); if (layoutManager instanceof GridLayoutManager) { if ((pos - adapter.getHeaderViews().size()) % spanCount == 0) // 如果是最后一列,则不需要绘制右边 return true; } return false; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { super.getItemOffsets(outRect, view, parent, state); int itemPosition = parent.getChildAdapterPosition(view); int spanCount = getSpanCount(parent); int childCount = parent.getAdapter().getItemCount(); LRecyclerViewAdapter adapter = (LRecyclerViewAdapter) parent.getAdapter(); if (adapter.isFooter(itemPosition) || adapter.isHeader(itemPosition) || adapter.isRefreshHeader(itemPosition)) { //header,footer不进行绘制 outRect.set(0, 0, 0, 0); } else { if (!(parent.getLayoutManager() instanceof GridLayoutManager)) { //LinearLayoutManager if (itemPosition == (childCount - 2 - adapter.getHeaderViews().size())) outRect.set(0, 0, 0, 0); else outRect.set(0, 0, 0, verticalSpace); } else { //GridLayoutManager if (isLastRaw(parent, itemPosition, spanCount, childCount - 2 - adapter.getHeaderViews().size())) { //最后一行 if (isLastColumn(parent, itemPosition, spanCount)) { // 最后一行最后一列 outRect.set(0, 0, 0, verticalSpace); } else { // 最后一行不是最后一列 outRect.set(0, 0, horizontalSpace, verticalSpace); } } else { //最后一列 if (isLastColumn(parent, itemPosition, spanCount)) { // 最后一列最后一行 outRect.set(0, 0, 0, verticalSpace); } else { // 最后一列非最后一行 outRect.set(0, 0, horizontalSpace, verticalSpace); } } } } } public static class Builder { private Context mContext; private Resources mResources; private int mHorizontal; private int mVertical; private int mColour; public Builder(Context context) { mContext = context; mResources = context.getResources(); mHorizontal = 0; mVertical = 0; mColour = Color.BLACK; } /** * Sets the divider colour * * @param resource the colour resource id * @return the current instance of the Builder */ public Builder setColorResource(@ColorRes int resource) { setColor(ContextCompat.getColor(mContext, resource)); return this; } /** * Sets the divider colour * * @param color the colour * @return the current instance of the Builder */ public Builder setColor(@ColorInt int color) { mColour = color; return this; } //通过dp设置垂直间距 public Builder setVertical(@DimenRes int vertical) { this.mVertical = mResources.getDimensionPixelSize(vertical); return this; } //通过px设置垂直间距 public Builder setVertical(float mVertical) { this.mVertical = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mVertical, mResources.getDisplayMetrics()); return this; } //通过dp设置水平间距 public Builder setHorizontal(@DimenRes int horizontal) { this.mHorizontal = mResources.getDimensionPixelSize(horizontal); return this; } //通过px设置水平间距 public Builder setHorizontal(float horizontal) { this.mHorizontal = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, horizontal, mResources.getDisplayMetrics()); return this; } /** * Instantiates a DividerDecoration with the specified parameters. * * @return a properly initialized DividerDecoration instance */ public GridItemDecoration build() { return new GridItemDecoration(mHorizontal, mVertical, mColour); } } }