I ended up with this implementation in my project. You can pass different dimension in constructor to set the spacing between the items. As I wrote in the class' KDoc, it will add (total parent space - child width) / 2
to the left of first and to the right of last item in order to center first and last items.
import android.graphics.Rect
import android.view.View
import androidx.annotation.DimenRes
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
/**
* Adds (total parent space - child width) / 2 to the left of first and to the right of last item (in order to center first and last items),
* and [spacing] between items.
*/
internal class OffsetItemDecoration constructor(
@DimenRes private val spacing: Int,
) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State,
) {
val itemPosition: Int = parent.getChildAdapterPosition(view)
if (itemPosition == RecyclerView.NO_POSITION) return
val spacingPixelSize: Int = parent.context.resources.getDimensionPixelSize(spacing)
when (itemPosition) {
0 ->
outRect.set(getOffsetPixelSize(parent, view), 0, spacingPixelSize / 2, 0)
parent.adapter!!.itemCount - 1 ->
outRect.set(spacingPixelSize / 2, 0, getOffsetPixelSize(parent, view), 0)
else ->
outRect.set(spacingPixelSize / 2, 0, spacingPixelSize / 2, 0)
}
}
private fun getOffsetPixelSize(parent: RecyclerView, view: View): Int {
val orientationHelper = OrientationHelper.createHorizontalHelper(parent.layoutManager)
return (orientationHelper.totalSpace - view.layoutParams.width) / 2
}
}