SnapLayoutInfoProvider

Function

Common
fun SnapLayoutInfoProvider(
    lazyListState: LazyListState,
    snapPosition: SnapPosition = SnapPosition.Center,
): SnapLayoutInfoProvider

A SnapLayoutInfoProvider for LazyLists.

Parameters

lazyListStateThe LazyListState with information about the current state of the list
snapPositionThe desired positioning of the snapped item within the main layout. This position should be considered with regard to the start edge of the item and the placement within the viewport.

Returns

A SnapLayoutInfoProvider that can be used with snapFlingBehavior
Common
fun SnapLayoutInfoProvider(
    lazyGridState: LazyGridState,
    snapPosition: SnapPosition = SnapPosition.Center,
) =
    object : SnapLayoutInfoProvider {
        private val layoutInfo: LazyGridLayoutInfo
            get() = lazyGridState.layoutInfo

        private val averageItemSize: Int
            get() {
                val layoutInfo = layoutInfo
                return if (layoutInfo.visibleItemsInfo.isEmpty()) {
                    0
                } else {
                    val numberOfItems = layoutInfo.visibleItemsInfo.size
                    layoutInfo.visibleItemsInfo.sumOf {
                        it.sizeOnMainAxis(layoutInfo.orientation)
                    } / numberOfItems
                }
            }

        override fun calculateApproachOffset(velocity: Float, decayOffset: Float): Float {
            return (decayOffset.absoluteValue - averageItemSize).coerceAtLeast(0.0f) *
                decayOffset.sign
        }

        override fun calculateSnapOffset(velocity: Float): Float {
            var distanceFromItemBeforeTarget = Float.NEGATIVE_INFINITY
            var distanceFromItemAfterTarget = Float.POSITIVE_INFINITY

            layoutInfo.visibleItemsInfo.fastForEach { item ->
                val distance =
                    calculateDistanceToDesiredSnapPosition(
                        mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
                        beforeContentPadding = layoutInfo.beforeContentPadding,
                        afterContentPadding = layoutInfo.afterContentPadding,
                        itemSize = item.sizeOnMainAxis(orientation = layoutInfo.orientation),
                        itemOffset = item.offsetOnMainAxis(orientation = layoutInfo.orientation),
                        itemIndex = item.index,
                        snapPosition = snapPosition,
                        itemCount = layoutInfo.totalItemsCount,
                    )

                if (distance <= 0 && distance > distanceFromItemBeforeTarget) {
                    distanceFromItemBeforeTarget = distance
                }

                if (distance >= 0 && distance < distanceFromItemAfterTarget) {
                    distanceFromItemAfterTarget = distance
                }
            }

            return calculateFinalOffset(
                with(lazyGridState.density) { calculateFinalSnappingItem(velocity) },
                distanceFromItemBeforeTarget,
                distanceFromItemAfterTarget,
            )
        }
    }

A SnapLayoutInfoProvider for LazyGrids.

Parameters

lazyGridStateThe LazyGridState with information about the current state of the grid
snapPositionThe desired positioning of the snapped item within the main layout. This position should be considered with regards to the start edge of the item and the placement within the viewport.

Returns

A SnapLayoutInfoProvider that can be used with snapFlingBehavior