Merge pull request #1765 from esensar/auto-grid-layout-manager

Move AutoGridLayoutManager from other apps into Commons for reuse
This commit is contained in:
Tibor Kaputa 2023-07-27 16:33:03 +02:00 committed by GitHub
commit dd5d48bc18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 1 deletions

View file

@ -0,0 +1,37 @@
package com.simplemobiletools.commons.views
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.max
/**
* RecyclerView GridLayoutManager but with automatic spanCount calculation.
*
* @param context The initiating view's context.
* @param itemWidth: Grid item width in pixels. Will be used to calculate span count.
*/
class AutoGridLayoutManager(
context: Context,
private var itemWidth: Int
) : MyGridLayoutManager(context, 1) {
init {
require(itemWidth >= 0) {
"itemWidth must be >= 0"
}
}
override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) {
val width = width
val height = height
if (itemWidth > 0 && width > 0 && height > 0) {
val totalSpace = if (orientation == VERTICAL) {
width - paddingRight - paddingLeft
} else {
height - paddingTop - paddingBottom
}
spanCount = max(1, totalSpace / itemWidth)
}
super.onLayoutChildren(recycler, state)
}
}

View file

@ -0,0 +1,43 @@
package com.simplemobiletools.commons.views
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import kotlin.math.max
/**
* RecyclerView StaggeredGridLayoutManager but with automatic spanCount calculation.
*
* @param context The initiating view's context.
* @param itemSize: Grid item size (width or height, depending on orientation) in pixels. Will be used to calculate span count.
*/
class AutoStaggeredGridLayoutManager(
private var itemSize: Int,
orientation: Int,
) : StaggeredGridLayoutManager(1, orientation) {
init {
require(itemSize >= 0) {
"itemSize must be >= 0"
}
}
override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) {
val width = width
val height = height
if (itemSize > 0 && width > 0 && height > 0) {
val totalSpace = if (orientation == VERTICAL) {
width - paddingRight - paddingLeft
} else {
height - paddingTop - paddingBottom
}
postOnAnimation {
spanCount = max(1, totalSpace / itemSize)
}
}
super.onLayoutChildren(recycler, state)
}
// fixes crash java.lang.IndexOutOfBoundsException: Inconsistency detected...
// taken from https://stackoverflow.com/a/33985508/1967672
override fun supportsPredictiveItemAnimations() = false
}

View file

@ -4,7 +4,7 @@ import android.content.Context
import android.util.AttributeSet
import androidx.recyclerview.widget.GridLayoutManager
class MyGridLayoutManager : GridLayoutManager {
open class MyGridLayoutManager : GridLayoutManager {
constructor(context: Context, spanCount: Int) : super(context, spanCount)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)