感谢:http://www.jianshu.com/p/d58cbd61c40a _SOLID
之前UI有个比较特别的需求,一个gridview形式的列表,但是四周都有白色的分割线:
类似这个效果,一开始以为会比较简单,然后写了之后才发现,目前网上找到的大部分方法话分割线都是省略掉屏幕边缘的部分的,
即第一行 第一列 最后一行 最后一列的没有分割线的
http://blog.csdn.net/lmj623565791/article/details/45059587
如hongyang大神的这个文章中就是这种典型的gridview的ItemDecoration
于是在掘金和github找了很久,终于找到一个符合一般要求的—最后一行也与分割线,虽然第一行还是没有,不过既然最后一行都有了,第一韩有也不难了
http://www.jianshu.com/p/d58cbd61c40a
自定义ItemDecoration这个问题你真的注意到了吗—–_SOLID
这个博客贴出的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;
}
}