Recyclerview ItemDecoration 通用分割线
程序员文章站
2022-04-06 20:14:02
public class CommonDividerItemDecoration extends RecyclerView.ItemDecoration { public final static int HORIZONTAL = LinearLayoutManager.HORIZONTAL; public final static int VERTICAL = LinearLayoutManager.VERTICAL; public final static float ....
目前还没有试验瀑布流 只写了list 和 grid 待完善
public class CommonDividerItemDecoration extends RecyclerView.ItemDecoration {
public final static int HORIZONTAL = LinearLayoutManager.HORIZONTAL;
public final static int VERTICAL = LinearLayoutManager.VERTICAL;
public final static float DEFAULT_SPACE = 0.5f;
private Context mContext;
private int mOrientation;
private int mRectSpace;
private int mLeftEdgeSpace;
private int mTopEdgeSpace;
private int mRightEdgeSpace;
private int mBottomEdgeSpace;
private boolean isIncludeLeft;
private boolean isIncludeTop;
private boolean isIncludeRight;
private boolean isIncludeBottom;
private Paint mPaint;
private int mPaintColor;
private int mMaxSpanGroupIndex;
private CommonDividerItemDecoration(Builder builder) {
this.mContext = builder.context;
this.mOrientation = builder.orientation;
this.mRectSpace = builder.rectSpace;
this.mLeftEdgeSpace = builder.leftEdgeSpace;
this.mTopEdgeSpace = builder.topEdgeSpace;
this.mRightEdgeSpace = builder.rightEdgeSpace;
this.mBottomEdgeSpace = builder.bottomEdgeSpace;
this.isIncludeLeft = builder.isIncludeLeft;
this.isIncludeTop = builder.isIncludeTop;
this.isIncludeRight = builder.isIncludeRight;
this.isIncludeBottom = builder.isIncludeBottom;
this.mPaintColor = builder.paintColor;
init();
}
private void init() {
this.mPaint = new Paint();
this.mPaint.setAntiAlias(true);
this.mPaint.setStyle(Paint.Style.FILL);
this.mPaint.setColor(this.mPaintColor);
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int childCount = Objects.requireNonNull(parent.getAdapter()).getItemCount();
if (childCount == 0) return;
int position = parent.getChildAdapterPosition(view);
view.setTag(position);
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
int spanCount = gridLayoutManager.getSpanCount();
mMaxSpanGroupIndex = spanSizeLookup.getSpanGroupIndex(parent.getAdapter().getItemCount() - 1, spanCount);
if (isFirsColumn(position, spanCount)) {
if (isFirstRow(position, spanCount)) {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, isIncludeTop ? mTopEdgeSpace : 0, mRectSpace, mRectSpace);
} else if (isLastRow(position, spanCount, childCount)) {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, 0, mRectSpace, isIncludeBottom ? mBottomEdgeSpace : 0);
} else {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, 0, mRectSpace, mRectSpace);
}
} else if (isFirstRow(position, spanCount)) {
if (isLastColumn(position, spanCount)) {
outRect.set(0, isIncludeTop ? mTopEdgeSpace : 0, isIncludeRight ? mRightEdgeSpace : 0, mRectSpace);
} else {
outRect.set(0, isIncludeTop ? mTopEdgeSpace : 0, mRectSpace, mRectSpace);
}
} else if (isLastColumn(position, spanCount)) {
if (isLastRow(position, spanCount, childCount)) {
outRect.set(0, 0, isIncludeRight ? mRightEdgeSpace : 0, isIncludeBottom ? mBottomEdgeSpace : 0);
} else {
outRect.set(0, 0, isIncludeRight ? mRightEdgeSpace : 0, mRectSpace);
}
} else if (isLastRow(position, spanCount, childCount)) {
outRect.set(0, 0, mRectSpace, isIncludeBottom ? mBottomEdgeSpace : 0);
} else {
outRect.set(0, 0, mRectSpace, mRectSpace);
}
} else if (layoutManager instanceof LinearLayoutManager) {
if (mOrientation == VERTICAL) {
if (position == 0) {//默认的只有一条数据的话 底部分割线保留 如果需要特殊处理再说
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, isIncludeTop ? mTopEdgeSpace : 0
, isIncludeRight ? mRightEdgeSpace : 0, mRectSpace);
} else if (position == childCount - 1) {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, 0
, isIncludeRight ? mRightEdgeSpace : 0, isIncludeBottom ? mBottomEdgeSpace : 0);
} else {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, 0
, isIncludeRight ? mRightEdgeSpace : 0, mRectSpace);
}
} else {
if (position == 0) {
outRect.set(isIncludeLeft ? mLeftEdgeSpace : 0, isIncludeTop ? mTopEdgeSpace : 0
, mRectSpace, isIncludeBottom ? mBottomEdgeSpace : 0);
} else if (position == childCount - 1) {
outRect.set(0, isIncludeTop ? mTopEdgeSpace : 0
, isIncludeRight ? mRightEdgeSpace : 0, isIncludeBottom ? mBottomEdgeSpace : 0);
} else {
outRect.set(0, isIncludeTop ? mTopEdgeSpace : 0
, mRectSpace, isIncludeBottom ? mBottomEdgeSpace : 0);
}
}
} else {
if (mOrientation == VERTICAL) {
} else {
}
}
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
drawGridSpace(c, parent);
} else if (layoutManager instanceof LinearLayoutManager) {
if (mOrientation == VERTICAL) {
drawListVertical(c, parent);
} else {
drawListHorizontal(c, parent);
}
} else {
//TODO
}
}
private void drawListVertical(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
final int itemCount = Objects.requireNonNull(parent.getAdapter()).getItemCount();
if (childCount == 0) return;
final int left = isIncludeLeft ? parent.getPaddingLeft() + mLeftEdgeSpace : parent.getPaddingLeft();
final int right = isIncludeRight ? parent.getWidth() - parent.getPaddingRight() - mRightEdgeSpace : parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int position = parent.getChildLayoutPosition(child);
if (position == 0) {
if (isIncludeTop) {
final int top = child.getTop() - params.topMargin - mTopEdgeSpace;
final int bottom = top + mTopEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mRectSpace;
c.drawRect(left, top, right, bottom, mPaint);
} else if (position == itemCount - 1) {
if (isIncludeBottom) {
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mBottomEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
} else {
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mRectSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
}
drawLeftOrRightSpace(c, parent);
}
public void drawLeftOrRightSpace(Canvas c, RecyclerView parent) {
if (isIncludeLeft) {
final int left = parent.getPaddingLeft();
final int top = parent.getPaddingTop();
final int right = left + mLeftEdgeSpace;
final int bottom = parent.getHeight() - parent.getPaddingBottom();
c.drawRect(left, top, right, bottom, mPaint);
}
if (isIncludeRight) {
final int left = parent.getWidth() - parent.getPaddingRight() - mRightEdgeSpace;
final int top = parent.getPaddingTop();
final int right = left + mRightEdgeSpace;
final int bottom = parent.getHeight() - parent.getPaddingBottom();
c.drawRect(left, top, right, bottom, mPaint);
}
}
private void drawListHorizontal(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
int itemCount = Objects.requireNonNull(parent.getAdapter()).getItemCount();
if (childCount == 0) return;
final int top = isIncludeTop ? parent.getPaddingTop() + mTopEdgeSpace : parent.getPaddingTop();
final int bottom = isIncludeBottom ? parent.getHeight() - parent.getPaddingBottom() - mBottomEdgeSpace : parent.getHeight() - parent.getPaddingBottom();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int position = parent.getChildLayoutPosition(child);
if (position == 0) {
if (isIncludeLeft) {
final int left = child.getLeft() - params.leftMargin - mLeftEdgeSpace;
final int right = left + mLeftEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
final int left = child.getRight() + params.rightMargin;
final int right = left + mRectSpace;
c.drawRect(left, top, right, bottom, mPaint);
} else if (position == itemCount - 1) {
if (isIncludeRight) {
final int left = child.getRight() + params.rightMargin;
final int right = left + mRightEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
} else {
final int left = child.getRight() + params.rightMargin;
final int right = left + mRectSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
}
drawTopOrBottomSpace(c, parent);
}
private void drawTopOrBottomSpace(Canvas c, RecyclerView parent) {
if (isIncludeTop) {
final int left = parent.getPaddingLeft();
final int top = parent.getPaddingTop();
final int right = parent.getWidth() - parent.getPaddingRight();
final int bottom = top + mTopEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
if (isIncludeBottom) {
final int left = parent.getPaddingLeft();
final int top = parent.getHeight() - parent.getPaddingBottom() - mBottomEdgeSpace;
final int right = parent.getWidth() - parent.getPaddingRight();
final int bottom = top + mBottomEdgeSpace;
c.drawRect(left, top, right, bottom, mPaint);
}
}
private void drawGridSpace(Canvas canvas, RecyclerView parent) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) parent.getLayoutManager();
int spanCount = Objects.requireNonNull(gridLayoutManager).getSpanCount();
GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
int childCount = parent.getChildCount();
int top, bottom, left, right;
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
int position = parent.getChildLayoutPosition(child);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
int spanGroupIndex = spanSizeLookup.getSpanGroupIndex(position, spanCount);
int spanSize = spanSizeLookup.getSpanSize(position);
int spanIndex = spanSizeLookup.getSpanIndex(position, spanCount);
// 画bottom分割线,如果没到达底部,绘制bottom
top = child.getBottom() + layoutParams.bottomMargin;
bottom = top + mRectSpace;
left = child.getLeft() - layoutParams.leftMargin;
right = child.getRight() + layoutParams.rightMargin + mRectSpace;
canvas.drawRect(left, top, right, bottom, mPaint);
// 画right分割线
top = child.getTop() - layoutParams.topMargin;
bottom = child.getBottom() + layoutParams.bottomMargin;
left = child.getRight() + layoutParams.rightMargin;
right = left + mRectSpace;
canvas.drawRect(left, top, right, bottom, mPaint);
}
drawLeftOrRightSpace(canvas, parent);
drawTopOrBottomSpace(canvas, parent);
}
public static class Builder {
private Context context;
private int orientation = VERTICAL;
private int rectSpace;
private int leftEdgeSpace;
private int topEdgeSpace;
private int rightEdgeSpace;
private int bottomEdgeSpace;
private boolean isIncludeLeft;
private boolean isIncludeTop;
private boolean isIncludeRight;
private boolean isIncludeBottom;
private int paintColor = Constants.COLOR.WHITE_SMOKE;
public Builder(Context context) {
this.context = context;
rectSpace = DpUtils.dip2px(context, DEFAULT_SPACE);
leftEdgeSpace = topEdgeSpace = rightEdgeSpace = bottomEdgeSpace = rectSpace;
}
public Context getContext() {
return context;
}
public Builder setContext(Context mContext) {
this.context = mContext;
return this;
}
public int getOrientation() {
return orientation;
}
public Builder setOrientation(int orientation) {
this.orientation = orientation;
return this;
}
public int getRectSpace() {
return rectSpace;
}
public Builder setRectSpace(float rectSpace) {
this.rectSpace = DpUtils.dip2px(context, rectSpace);
return this;
}
public int getLeftEdgeSpace() {
return leftEdgeSpace;
}
public Builder setLeftEdgeSpace(int leftEdgeSpace) {
this.leftEdgeSpace = DpUtils.dip2px(context, leftEdgeSpace);
return this;
}
public int getTopEdgeSpace() {
return topEdgeSpace;
}
public Builder setTopEdgeSpace(int topEdgeSpace) {
this.topEdgeSpace = DpUtils.dip2px(context, topEdgeSpace);
return this;
}
public int getRightEdgeSpace() {
return rightEdgeSpace;
}
public Builder setRightEdgeSpace(int rightEdgeSpace) {
this.rightEdgeSpace = DpUtils.dip2px(context, rightEdgeSpace);
return this;
}
public int getBottomEdgeSpace() {
return bottomEdgeSpace;
}
public Builder setBottomEdgeSpace(int bottomEdgeSpace) {
this.bottomEdgeSpace = DpUtils.dip2px(context, bottomEdgeSpace);
return this;
}
public boolean isIncludeLeft() {
return isIncludeLeft;
}
public Builder setIncludeLeft(boolean includeLeft) {
this.isIncludeLeft = includeLeft;
return this;
}
public boolean isIncludeTop() {
return isIncludeTop;
}
public Builder setIncludeTop(boolean includeTop) {
this.isIncludeTop = includeTop;
return this;
}
public boolean isIncludeRight() {
return isIncludeRight;
}
public Builder setIncludeRight(boolean includeRight) {
this.isIncludeRight = includeRight;
return this;
}
public boolean isIncludeBottom() {
return isIncludeBottom;
}
public Builder setIncludeBottom(boolean includeBottom) {
this.isIncludeBottom = includeBottom;
return this;
}
public int getPaintColor() {
return paintColor;
}
public Builder setPaintColor(int paintColor) {
this.paintColor = paintColor;
return this;
}
public CommonDividerItemDecoration build() {
return new CommonDividerItemDecoration(this);
}
}
/**
* 判断是不是第一行
*
* @param pos item index in adapter
* @param spanCount your grid spanCount
* @return true or false
*/
private boolean isFirstRow(int pos, int spanCount) {
return (pos / spanCount) == 0;
}
/**
* 判断是不是最后一行
*
* @param pos item index in adapter
* @param spanCount your grid spanCount
* @param childCount your total ItemCount
* @return true or false
*/
private boolean isLastRow(int pos, int spanCount, int childCount) {
int ranger = childCount % spanCount;
if (ranger == 0) {
ranger = spanCount;
}
childCount = childCount - ranger;
return pos >= childCount;
}
/**
* 判断是不是第一列
*
* @param pos item index in adapter
* @param spanCount your grid spanCount
* @return true or false
*/
private boolean isFirsColumn(int pos, int spanCount) {
return pos % spanCount == 0;
}
/**
* 判断是不是最后一列
*
* @param pos item index in adapter
* @param spanCount your grid spanCount
* @return true or false
*/
private boolean isLastColumn(int pos, int spanCount) {
return (pos + 1) % spanCount == 0;
}
}
本文地址:https://blog.csdn.net/xielunyan666/article/details/107908480
推荐阅读
-
Android 中RecyclerView通用适配器的实现
-
Android 给RecyclerView添加分割线的具体步骤(分享)
-
Android RecyclerView 复用错乱通用解法详解
-
RecyclerView底部分割线去除的方法
-
android中RecyclerView自定义分割线实现
-
Android实现RecyclerView添加分割线的简便方法
-
Android Recyclerview 网格布局分割线
-
Android RecyclerView实现水平、垂直方向分割线
-
Android中自定义RecyclerView.ItemDecoration
-
Android 中RecyclerView通用适配器的实现