支持绘制网格布局和瀑布流的网格线
/**
* 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);
}
}
}