效果如下
image.png
分解:
1闻书、自定RecyclerView.ItemDecoration
2般哼、通過getItemOffsets 給每一個 Item 設置偏移量,相當于留出間距
3惠窄、通過onDraw 在留出的間距上繪制想要的邊線
源碼:
//主要是繪制了每一個item 的右邊和下邊線條蒸眠,最后一列的右邊沒有繪制,最后一行的底部不做繪制
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {
private int space;
private Paint paint = new Paint();
public GridSpaceItemDecoration() {
space = SizeUtils.dp2px(1f);
paint.setColor(Color.parseColor("#f7f7f7"));
paint.setStrokeWidth(space);
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
drawHorizontal(c, parent);
drawVertical(c, parent);
}
//圖中橫向的紅色線條繪制杆融,為了便于區(qū)分設置的兩個顏色楞卡,代碼里已經(jīng)去掉
public void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin + space;
int top = child.getBottom() + params.bottomMargin;
int bottom = top + space;
c.drawRect(new Rect(left, top, right, bottom), paint);
}
}
//圖中縱向的綠色線條繪制,為了便于區(qū)分設置的兩個顏色脾歇,代碼里已經(jīng)去掉
public void drawVertical(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + space;
c.drawRect(new Rect(left, top, right, bottom), paint);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int itemPosition = parent.getChildLayoutPosition(view);
int spanCount = getSpanCount(parent);
double count = Math.ceil((double) parent.getAdapter().getItemCount() / (double) spanCount);//總行數(shù)
//double currentCount = Math.ceil((double) (itemPosition + 1) / spanCount);//當前行數(shù)
if (count == 1) {
// 如果是最后一列蒋腮,則不需要繪制右邊
if (isLastColumn(itemPosition, parent)) {
outRect.set(0, 0, 0, 0);
} else {
outRect.set(0, 0, space, 0);
}
} else {
if (isLastRow(itemPosition, parent)) {
if (isLastColumn(itemPosition, parent)) {
outRect.set(0, 0, 0, 0);
} else {
outRect.set(0, 0, space, 0);
}
} else {
if (isLastColumn(itemPosition, parent)) {
outRect.set(0, 0, 0, space);
} else {
outRect.set(0, 0, space, space);
}
}
}
}
private boolean isLastRow(int itemPosition, RecyclerView parent) {
int spanCount = getSpanCount(parent);
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
//有多少列
if (layoutManager instanceof GridLayoutManager) {
int childCount = parent.getAdapter().getItemCount();
double count = Math.ceil((double) childCount / (double) spanCount);//總行數(shù)
double currentCount = Math.ceil((double) (itemPosition + 1) / spanCount);//當前行數(shù)
//最后當前數(shù)量小于總的
if (currentCount < count) {
return false;
}
}
return true;
}
private boolean isLastColumn(int itemPosition, RecyclerView parent) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
//有多少列
if (layoutManager instanceof GridLayoutManager) {
int spanCount = getSpanCount(parent);
if ((itemPosition + 1) % spanCount == 0) {//因為是從0可以所以要將ItemPosition先加1
return true;
}
}
return false;
}
private int getSpanCount(RecyclerView parent) {
if (parent.getLayoutManager() instanceof GridLayoutManager) {
return ((GridLayoutManager) parent.getLayoutManager()).getSpanCount();
} else {
return 1;
}
}
}
歡迎大家留言討論