RecyclerView ItemDecoration Top suspension


Too lazy to type, directly on the code

package com.lx.kotlin.reader.adapter.help import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.Rect import android.support.v4.content.ContextCompat import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.view.View The import com. Lx. Kotlin. Reader. R import com. Lx. Kotlin. Reader. Utils. Formatter / * * * * data construct RecyclerView top suspension absorption effect: * Created on 18-1-5 PM 3:56 */ Class ItemTopDecoration(val context: context, val data: MutableList<ItemDecData>) : RecyclerView.ItemDecoration() { private var topHeight: Float = 0F private val spacing = Formatter.dip2px(context, 4F) init { val paint = Paint() paint.textSize = Formatter.sp2px(context, 14.toFloat()).toFloat() paint.getTextBounds("test", 0, 4, Rect()) val fontMetrics = paint.fontMetricsInt var absHeight = Math.abs(fontMetrics.top - fontMetrics.bottom) topHeight = (absHeight + 20).toFloat() } override fun onDraw(c: Canvas? , parent: RecyclerView? , state: RecyclerView.State?) {super.ondraw (c, parent, state) // Get the actual left and right items (minus the parent padding) val left = parent!! .paddingLeft.toFloat() val right = (parent.width - parent.paddingRight).toFloat() for (i in 0 until parent.childCount) { // If I is 0, the index will be the first one. Instead of all the first child = parent. Val getChildAt (I) val index = parent. GetChildAdapterPosition (child) if (! CheckInGroupFirst (index)) {continue} // Each group has space for the first item to draw val top = child.top-topheight-spacing val bottom = Val paint = paint () paint. Color = ContextCompat. GetColor (ContextCompat. R.color.colorRefresh2) c!! DrawRect (left, top, right, bottom, paint); paint. Color = ContextCompat. R.color.colorWhite) paint.textSize = Formatter.sp2px(context, 12.toFloat()).toFloat() paint.textAlign = Paint.Align.LEFT paint.isAntiAlias = true var str = getText(index) paint.getTextBounds(str, 0, str.length, Rect()) val fontMetrics = paint.getFontMetricsInt() val baseline = (bottom + top - fontMetrics.bottom - fontMetrics.top)  / 2 c.drawText(str, left + 20, baseline, paint) } } override fun onDrawOver(c: Canvas? , parent: RecyclerView? , state: RecyclerView.State?) {super.onDrawOver(c, parent, state) // Get the true left and right of item (minus the parent padding) val left = parent!! .paddingLeft.toFloat() val right = (parent.width - parent.paddingRight).toFloat() var index = (parent.layoutManager as LinearLayoutManager). FindFirstVisibleItemPosition () child = parent. Val getChildAt (0) / / the first item in each group leaves room to draw var top = 0 f var bottom = 0F if (checkInGroupFirst(index+1)) { bottom = Math.min(topHeight + parent.paddingTop, Child.bottom.tofloat () +spacing)} else {bottom = topHeight + parent.paddingtop} top = bottom-topheight // Draw the background color val  paint = Paint() paint.color = ContextCompat.getColor(context, R.color.colorRefresh2) c!! DrawRect (left, top, right, bottom, paint); paint. Color = ContextCompat. R.color.colorWhite) paint.textSize = Formatter.sp2px(context, 12.toFloat()).toFloat() paint.textAlign = Paint.Align.LEFT paint.isAntiAlias = true var text = getText(index) paint.getTextBounds(text, 0, text.length, Rect()) val fontMetrics = paint.fontMetricsInt val baseline = (bottom + top - fontMetrics.bottom - fontMetrics.top) / 2 Override fun getItemOffsets(outRect: Rect? , view: View? , parent: RecyclerView? , state: RecyclerView.State?) { super.getItemOffsets(outRect, view, parent, state) var pos = parent!! .getChildAdapterPosition(view) outRect!! .left = spacing outRect!! .right = spacing outRect.bottom = spacing if (checkInGroupFirst(pos)) { outRect!! .top = topHeight.toInt() + spacing } } private fun checkInGroupFirst(pos: Int): Boolean { for (item in data) { if (pos == item.pos) return true } return false } private fun getText(pos: Int): String { var id = getFirstId(pos) for (item in data){ if (id == item.pos)return item.text } return "" } private fun getFirstId(pos: Int): Int { var lastData: ItemDecData? = null var i = 0 for (item in data) { i++ if (pos == item.pos) { return item.pos }else if (pos < item.pos) { return lastData!! .pos } else if(i == data.size){ return item.pos } lastData = item } return 0 } }Copy the code