RecyclerView在GridLayoutManager情況下實現四周都有分割線的ItemDecoration
阿新 • • 發佈:2019-02-16
之前UI有個比較特別的需求,一個gridview形式的列表,但是四周都有白色的分割線:
類似這個效果,一開始以為會比較簡單,然後寫了之後才發現,目前網上找到的大部分方法話分割線都是省略掉螢幕邊緣的部分的,
即第一行 第一列 最後一行 最後一列的沒有分割線的
於是在掘金和github找了很久,終於找到一個符合一般要求的—最後一行也與分割線,雖然第一行還是沒有,不過既然最後一行都有了,第一韓有也不難了
這個部落格貼出的ItemDecoration正好拿來改造一番
關鍵程式碼在於:
private boolean isfirstRow(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
// childCount = childCount - childCount % spanCount;
int lines = childCount % spanCount == 0 ? childCount / spanCount : childCount / spanCount + 1;
//如是第一行則返回true
if ((pos / spanCount + 1) == 1) {
return true;
} else {
return false;
}
} 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 {
// 如果是最後一行,則不需要繪製底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
在這個方法裡判斷當前是否是第一行 (pos / spanCount + 1) == 1 這個就是關鍵程式碼
然後在getItemOffsets()方法中做一個判斷
if (isfirstRow) {
top = (spanCount - 1) * mDividerWidth / spanCount;
} else {
top = 0;
}
outRect.set(left, top, right, bottom);
計算item的偏差值,如果是第一行則set上去.
一下為全部程式碼:
package Tools;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.ColorInt;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
/**
* Gridview
* 四周都是分割線的ItemDecoration,因為網上都是RecyclerView的邊框部分沒有分割線,主要程式碼在於用isfirstRow去判斷
* Created by _SOLID
* Date:2016/10/8
* Time:16:50
* Desc:
*/
public class GridDividerItemDecoration extends RecyclerView.ItemDecoration {
private Paint mPaint;
private int mDividerWidth;
public GridDividerItemDecoration(int height, @ColorInt int color) {
mDividerWidth = height;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
boolean isLastRow = isLastRow(parent, itemPosition, spanCount, childCount);
boolean isfirstRow = isfirstRow(parent, itemPosition, spanCount, childCount);
int top;
int left;
int right;
int bottom;
int eachWidth = (spanCount - 1) * mDividerWidth / spanCount;
int dl = mDividerWidth - eachWidth;
left = itemPosition % spanCount * dl;
right = eachWidth - left;
bottom = mDividerWidth;
//Log.e("zzz", "itemPosition:" + itemPosition + " |left:" + left + " right:" + right + " bottom:" + bottom);
// if (isLastRow) {
// bottom = 0;
// }
if (isfirstRow) {
top = (spanCount - 1) * mDividerWidth / spanCount;
} else {
top = 0;
}
outRect.set(left, top, right, bottom);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
draw(c, parent);
}
//繪製橫向 item 分割線
private void draw(Canvas canvas, RecyclerView parent) {
int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
//畫水平分隔線
int left = child.getLeft();
int right = child.getRight();
int top = child.getBottom() + layoutParams.bottomMargin;
int bottom = top + mDividerWidth;
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
//畫垂直分割線
top = child.getTop();
bottom = child.getBottom() + mDividerWidth;
left = child.getRight() + layoutParams.rightMargin;
right = left + mDividerWidth;
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}
private boolean isLastColumn(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;
}
private boolean isLastRow(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
// childCount = childCount - childCount % spanCount;
int lines = childCount % spanCount == 0 ? childCount / spanCount : childCount / spanCount + 1;
return lines == pos / spanCount + 1;
} 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 {
// 如果是最後一行,則不需要繪製底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
private boolean isfirstRow(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
// childCount = childCount - childCount % spanCount;
int lines = childCount % spanCount == 0 ? childCount / spanCount : childCount / spanCount + 1;
//如是第一行則返回true
if ((pos / spanCount + 1) == 1) {
return true;
} else {
return false;
}
} 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 {
// 如果是最後一行,則不需要繪製底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
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;
}
}