这是效果图:
这是代码(用kotlin写的有点装):
class GridLayoutDivider(width:Int,color:Int) : RecyclerView.ItemDecoration() {
private var mWidth = width
private var mColor = color
private var mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
init {
mPaint.color = mColor
}
override fun onDraw(c: Canvas?, parent: RecyclerView?, state: RecyclerView.State?) {
super.onDraw(c, parent, state)
draw(c,parent)
}
private fun draw(canvas: Canvas?, parent: RecyclerView?) {
val childSize = parent?.childCount
for (i in 0 until childSize!!) {
val child = parent?.getChildAt(i)
val layoutParams = child?.layoutParams as RecyclerView.LayoutParams
//画水平分隔线
var left = child.left - layoutParams.leftMargin - mWidth
var right = child.right + mWidth
var top = child.bottom + layoutParams.bottomMargin
var bottom = top + mWidth
if (mPaint != null) {
canvas?.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), mPaint)
if(isFirstRow(i,getSpanCount(parent),childSize,parent) ) {
top = if(isFirsSpan(i,getSpanCount(parent),childSize)) {
child.top + layoutParams.bottomMargin - mWidth
}else{
child.top + layoutParams.bottomMargin
}
bottom = top + mWidth
canvas?.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), mPaint)
}
}
//画垂直分割线
top = child.top - layoutParams.topMargin - mWidth
bottom = child.bottom + layoutParams.bottomMargin + mWidth
if (mPaint != null) {
left = child.right + layoutParams.rightMargin
right = left + mWidth
canvas?.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), mPaint)
if(isFirsSpan(i,getSpanCount(parent),childSize)) {
left = if(isFirstRow(i,getSpanCount(parent),childSize,parent)){
child.left + layoutParams.rightMargin - mWidth
}else {
child.left + layoutParams.rightMargin
}
right = left + mWidth
canvas?.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), mPaint)
}
}
}
}
override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
super.getItemOffsets(outRect, view, parent, state)
val itemPosition = (view?.layoutParams as RecyclerView.LayoutParams).viewLayoutPosition
val spanCount = getSpanCount(parent)
val childCount = parent?.adapter?.itemCount
val isFirstRow = isFirstRow(itemPosition,spanCount,childCount,parent)
val left: Int
val top: Int
val bottom : Int = mWidth
val right = mWidth
left = if(isFirsSpan(itemPosition,spanCount,childCount)) mWidth else 0
top = if (isFirstRow) mWidth else 0
outRect?.set(top, left, right, bottom)
}
private fun isFirsSpan(position: Int,spanCount: Int,childCount: Int?):Boolean{
return position % spanCount == 0
}
private fun isFirstRow(position: Int, spanCount: Int, childCount: Int?,parent:RecyclerView?): Boolean {
val layoutManager = parent?.layoutManager
if(layoutManager is GridLayoutManager){
return position / spanCount == 0
}else if( layoutManager is StaggeredGridLayoutManager){
if(layoutManager.orientation == StaggeredGridLayoutManager.VERTICAL) {
if (childCount != null) {
val i = childCount - childCount!! % spanCount
// 如果是最后一行,则不需要绘制底部
if (position >= i)
return true
}
}else {
// 如果是最后一行,则不需要绘制底部
if ((position + 1) % spanCount == 0) {
return true
}
}
}
return false
}
private fun getSpanCount(parent: RecyclerView?): Int {
if (parent != null) {
val layoutManager = parent.layoutManager
if(layoutManager is GridLayoutManager)
return layoutManager.spanCount
else if(layoutManager is StaggeredGridLayoutManager)
return layoutManager.spanCount
}
return 0
}
}