Last active
December 30, 2021 07:34
-
-
Save Gnzlt/8cebfd0d09cad2afbb62756d385398ae to your computer and use it in GitHub Desktop.
Android RecyclerView GridLayout DividerItemDecoration. Based on https://github.com/bignerdranch/simple-item-decoration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<shape xmlns:android="http://schemas.android.com/apk/res/android"> | |
<size android:width="8dp" | |
android:height="8dp"/> | |
<solid android:color="@android:color/transparent"/> | |
</shape> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Canvas | |
import android.graphics.Rect | |
import android.graphics.drawable.Drawable | |
import android.support.v7.widget.RecyclerView | |
import android.view.View | |
/** | |
* Sole constructor. Takes in [Drawable] objects to be used as | |
* horizontal and vertical dividers. | |
* | |
* @param horizontalDivider A divider `Drawable` to be drawn on the | |
* rows of the grid of the RecyclerView | |
* @param verticalDivider A divider `Drawable` to be drawn on the | |
* columns of the grid of the RecyclerView | |
* @param numColumns The number of columns in the grid of the RecyclerView | |
*/ | |
class GridDividerItemDecoration( | |
private var mHorizontalDivider: Drawable, | |
private var mVerticalDivider: Drawable, | |
private var mNumColumns: Int | |
) : RecyclerView.ItemDecoration() { | |
/** | |
* Draws horizontal and/or vertical dividers onto the parent RecyclerView. | |
* | |
* @param canvas The [Canvas] onto which dividers will be drawn | |
* @param parent The RecyclerView onto which dividers are being added | |
* @param state The current RecyclerView.State of the RecyclerView | |
*/ | |
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State?) { | |
drawHorizontalDividers(canvas, parent) | |
drawVerticalDividers(canvas, parent) | |
} | |
/** | |
* Determines the size and location of offsets between items in the parent | |
* RecyclerView. | |
* | |
* @param outRect The [Rect] of offsets to be added around the child view | |
* @param view The child view to be decorated with an offset | |
* @param parent The RecyclerView onto which dividers are being added | |
* @param state The current RecyclerView.State of the RecyclerView | |
*/ | |
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State?) { | |
super.getItemOffsets(outRect, view, parent, state) | |
val childIsInLeftmostColumn = parent.getChildAdapterPosition(view) % mNumColumns == 0 | |
if (!childIsInLeftmostColumn) { | |
outRect.left = mHorizontalDivider.intrinsicWidth | |
} | |
val childIsInFirstRow = parent.getChildAdapterPosition(view) < mNumColumns | |
if (!childIsInFirstRow) { | |
outRect.top = mVerticalDivider.intrinsicHeight | |
} | |
} | |
/** | |
* Adds horizontal dividers to a RecyclerView with a GridLayoutManager or its | |
* subclass. | |
* | |
* @param canvas The [Canvas] onto which dividers will be drawn | |
* @param parent The RecyclerView onto which dividers are being added | |
*/ | |
private fun drawHorizontalDividers(canvas: Canvas, parent: RecyclerView) { | |
val childCount = parent.childCount | |
val rowCount = childCount / mNumColumns | |
val lastRowChildCount = childCount % mNumColumns | |
for (i in 1 until mNumColumns) { | |
val lastRowChildIndex = if (i < lastRowChildCount) { | |
i + rowCount * mNumColumns | |
} else { | |
i + (rowCount - 1) * mNumColumns | |
} | |
val firstRowChild = parent.getChildAt(i) | |
val lastRowChild = parent.getChildAt(lastRowChildIndex) | |
val dividerTop = firstRowChild.top | |
val dividerRight = firstRowChild.left | |
val dividerLeft = dividerRight - mHorizontalDivider.intrinsicWidth | |
val dividerBottom = lastRowChild.bottom | |
mHorizontalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) | |
mHorizontalDivider.draw(canvas) | |
} | |
} | |
/** | |
* Adds vertical dividers to a RecyclerView with a GridLayoutManager or its | |
* subclass. | |
* | |
* @param canvas The [Canvas] onto which dividers will be drawn | |
* @param parent The RecyclerView onto which dividers are being added | |
*/ | |
private fun drawVerticalDividers(canvas: Canvas, parent: RecyclerView) { | |
val childCount = parent.childCount | |
val rowCount = childCount / mNumColumns | |
for (i in 1..rowCount) { | |
val rightmostChildIndex = if (i == rowCount) { | |
parent.childCount - 1 | |
} else { | |
i * mNumColumns + mNumColumns - 1 | |
} | |
val leftmostChild = parent.getChildAt(i * mNumColumns) | |
val rightmostChild = parent.getChildAt(rightmostChildIndex) | |
val dividerLeft = leftmostChild.left | |
val dividerBottom = leftmostChild.top | |
val dividerTop = dividerBottom - mVerticalDivider.intrinsicHeight | |
val dividerRight = rightmostChild.right | |
mVerticalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) | |
mVerticalDivider.draw(canvas) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment