RecyclerView 四周帶分割線的ItemDecoration
阿新 • • 發佈:2018-11-14
這是效果圖:
這是程式碼(用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) vallayoutParams = 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 + mWidthif (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 } }