Issue
Hey I want to show divider in top, middle and bottom in Recyclerview. How to add dividers and spaces between items in RecyclerView. It work to add divider in middle and bottom. But I cannot find to add divider on top of first item. Has anyone know how to achieve this? Thanks in advance.
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.letsgetchecked.app.R
class SimpleDividerItemDecoration(private val context: Context) : RecyclerView.ItemDecoration() {
private var drawable: Drawable? = ContextCompat.getDrawable(context, R.drawable.cloudy)
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val left: Int = parent.paddingLeft
val right: Int = parent.width - parent.paddingRight
val childCount: Int = parent.childCount
for (i in 0 until childCount) {
val child: View = parent.getChildAt(i)
val params = child.layoutParams as RecyclerView.LayoutParams
val top: Int = child.bottom + params.bottomMargin
val bottom: Int = top + drawable?.intrinsicHeight!!
drawable?.setBounds(left, top, right, bottom)
drawable?.draw(c)
}
}
}
Expected Output
What I am getting
Solution
You don't need to write your own class. The way you're doing it does not account for the thickness of the divider, so it could lead to inaccurate padding in your list items. Use the provided class DividerItemDecoration.
However, it is also missing a divider above the top item. Here's a class you can add as a second decoration. It draws a divider over only the first item, so you can customize it to look different from the rest, which I think is a good idea for usability reasons. I based it off the source of DividerItemDecoration so it properly accounts for padding and clipping.
class TopDividerItemDecoration(val context: Context) : RecyclerView.ItemDecoration() {
private val bounds = Rect()
private var _drawable: Drawable? =
context.obtainStyledAttributes(intArrayOf(android.R.attr.listDivider)).use {
it.getDrawable(0)
}
var drawable: Drawable
get() = _drawable
?: error("A drawable must be set before use. Current theme lacks default divider.")
set(value) {
_drawable = value
}
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
if (parent.layoutManager == null || parent.childCount == 0)
return
c.save()
if (parent.clipToPadding) {
c.clipRect(
parent.paddingLeft, parent.paddingTop, parent.width - parent.paddingRight,
parent.height - parent.paddingBottom
)
}
val child = parent.getChildAt(0)
parent.getDecoratedBoundsWithMargins(child, bounds)
val top = bounds.top + child.translationY.roundToInt()
val bottom = top + drawable.intrinsicHeight
drawable.setBounds(0, top, parent.width, bottom)
drawable.draw(c)
c.restore()
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
if (parent.getChildLayoutPosition(view) == 0) {
outRect.top += drawable.intrinsicHeight
}
}
}
Answered By - Tenfour04
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.