🌈 Create new beautiful Compose Gradients with our new wesite ->
Property

layoutInfo

The object of ScalingLazyListLayoutInfo calculated during the last layout pass.

Source set: Android
public val layoutInfo: ScalingLazyListLayoutInfo by
        derivedStateOf(referentialEqualityPolicy()) {
            val config = config.value
            if (config == null) {
                EmptyScalingLazyListLayoutInfo
            } else {
                // read list state once here to for performance reasons and to ensure consistency
                val lazyListLayoutInfo = lazyListState.layoutInfo
                val initialized = initialized.value

                val visibleItemsInfo = mutableListOf<ScalingLazyListItemInfo>()
                var newCenterItemIndex = 0
                var newCenterItemScrollOffset = 0
                val visible = initialized || config.localInspectionMode

                // The verticalAdjustment is used to allow for the extraPadding that the
                // ScalingLazyColumn employs to ensure that there are sufficient list items composed
                // by the underlying LazyList even when there is extreme scaling being applied that
                // could result in additional list items be eligible to be drawn.
                // It is important to adjust for this extra space when working out the viewport
                // center-line based coordinate system of the ScalingLazyList.
                val verticalAdjustment =
                    lazyListLayoutInfo.viewportStartOffset + config.extraPaddingPx

                // Find the item in the middle of the viewport
                val centralItemArrayIndex =
                    findItemNearestCenter(lazyListLayoutInfo, config, verticalAdjustment)
                if (centralItemArrayIndex != null) {
                    val originalVisibleItemsInfo = lazyListLayoutInfo.visibleItemsInfo
                    val centralItem = originalVisibleItemsInfo[centralItemArrayIndex]

                    // Place the center item
                    val centerItemInfo: ScalingLazyListItemInfo =
                        calculateItemInfo(
                            centralItem.offset,
                            centralItem,
                            verticalAdjustment,
                            config.viewportHeightPx,
                            config.viewportCenterLinePx(),
                            config.scalingParams,
                            config.beforeContentPaddingPx,
                            config.anchorType,
                            config.autoCentering,
                            visible,
                        )
                    visibleItemsInfo.add(centerItemInfo)

                    newCenterItemIndex = centerItemInfo.index
                    newCenterItemScrollOffset = -centerItemInfo.offset

                    // Find the adjusted position of the central item in the coordinate system of
                    // the
                    // underlying LazyColumn by adjusting for any scaling
                    val centralItemAdjustedUnderlyingOffset =
                        centralItem.offset +
                            ((centerItemInfo.startOffset(config.anchorType) -
                                    centerItemInfo.unadjustedStartOffset(config.anchorType)))
                                .roundToInt()

                    // Go Up
                    // nextItemBottomNoPadding uses the coordinate system of the underlying
                    // LazyList. It
                    // keeps track of the top of the next potential list item that is a candidate to
                    // be
                    // drawn in the viewport as we walk up the list items from the center. Going up
                    // involved making offset smaller/negative as the coordinate system of the
                    // LazyList
                    // starts at the top of the viewport. Note that the start of the lazy list
                    // coordinates starts at '- start content padding in pixels' and goes beyond the
                    // last visible list items to include the end content padding in pixels.

                    // centralItem.offset is a startOffset in the coordinate system of the
                    // underlying lazy list.
                    var nextItemBottomNoPadding =
                        centralItemAdjustedUnderlyingOffset - config.gapBetweenItemsPx

                    (centralItemArrayIndex - 1 downTo 0).forEach { ix ->
                        if (nextItemBottomNoPadding >= verticalAdjustment) {
                            val currentItem = lazyListLayoutInfo.visibleItemsInfo[ix]
                            if (
                                !discardAutoCenteringListItem(
                                    config,
                                    lazyListLayoutInfo,
                                    currentItem,
                                )
                            ) {
                                val itemInfo =
                                    calculateItemInfo(
                                        nextItemBottomNoPadding - currentItem.size,
                                        currentItem,
                                        verticalAdjustment,
                                        config.viewportHeightPx,
                                        config.viewportCenterLinePx(),
                                        config.scalingParams,
                                        config.beforeContentPaddingPx,
                                        config.anchorType,
                                        config.autoCentering,
                                        visible,
                                    )
                                visibleItemsInfo.add(0, itemInfo)
                                nextItemBottomNoPadding =
                                    nextItemBottomNoPadding -
                                        itemInfo.size -
                                        config.gapBetweenItemsPx
                            }
                        } else {
                            return@forEach
                        }
                    }

                    // Go Down
                    // nextItemTopNoPadding uses the coordinate system of the underlying LazyList.
                    // It
                    // keeps track of the top of the next potential list item that is a candidate to
                    // be
                    // drawn in the viewport as we walk down the list items from the center.
                    var nextItemTopNoPadding =
                        centralItemAdjustedUnderlyingOffset +
                            centerItemInfo.size +
                            config.gapBetweenItemsPx

                    (((centralItemArrayIndex + 1) until originalVisibleItemsInfo.size)).forEach { ix
                        ->
                        if (
                            (nextItemTopNoPadding - config.viewportHeightPx) <= verticalAdjustment
                        ) {
                            val currentItem = lazyListLayoutInfo.visibleItemsInfo[ix]
                            if (
                                !discardAutoCenteringListItem(
                                    config,
                                    lazyListLayoutInfo,
                                    currentItem,
                                )
                            ) {
                                val itemInfo =
                                    calculateItemInfo(
                                        nextItemTopNoPadding,
                                        currentItem,
                                        verticalAdjustment,
                                        config.viewportHeightPx,
                                        config.viewportCenterLinePx(),
                                        config.scalingParams,
                                        config.beforeContentPaddingPx,
                                        config.anchorType,
                                        config.autoCentering,
                                        visible,
                                    )

                                visibleItemsInfo.add(itemInfo)
                                nextItemTopNoPadding += itemInfo.size + config.gapBetweenItemsPx
                            }
                        } else {
                            return@forEach
                        }
                    }
                }
                val totalItemsCount =
                    if (config.autoCentering != null) {
                        (lazyListLayoutInfo.totalItemsCount - 2).coerceAtLeast(0)
                    } else {
                        lazyListLayoutInfo.totalItemsCount
                    }

                // Decide if we are ready for the 2nd stage of initialization
                // 1. We are not yet initialized and

                val readyForInitialScroll =
                    if (!initialized) {
                        // 1. autoCentering is off or
                        // 2. The list has no items or
                        // 3. the before content autoCentering Spacer has been sized.
                        // NOTE: It is possible, if the first real item in the list is large, that
                        // the size
                        // of the Spacer is 0.
                        config.autoCentering == null ||
                            (lazyListLayoutInfo.visibleItemsInfo.size >= 2 &&
                                (
                                // or Empty list (other than the 2 spacers)
                                lazyListLayoutInfo.visibleItemsInfo.size == 2 ||
                                    // or first item is correctly size
                                    topSpacerIsCorrectlySized(
                                        config,
                                        lazyListLayoutInfo.visibleItemsInfo,
                                        lazyListLayoutInfo.totalItemsCount,
                                    )))
                    } else {
                        // We are already initialized and have an incomplete scroll to finish
                        incompleteScrollItem.value != null
                    }

                DefaultScalingLazyListLayoutInfo(
                    internalVisibleItemsInfo = visibleItemsInfo,
                    totalItemsCount = totalItemsCount,
                    viewportStartOffset =
                        lazyListLayoutInfo.viewportStartOffset + config.extraPaddingPx,
                    viewportEndOffset =
                        lazyListLayoutInfo.viewportEndOffset - config.extraPaddingPx,
                    centerItemIndex = if (initialized) newCenterItemIndex else 0,
                    centerItemScrollOffset = if (initialized) newCenterItemScrollOffset else 0,
                    reverseLayout = config.reverseLayout,
                    orientation = lazyListLayoutInfo.orientation,
                    viewportSize =
                        IntSize(
                            width = lazyListLayoutInfo.viewportSize.width,
                            height =
                                lazyListLayoutInfo.viewportSize.height - config.extraPaddingPx * 2,
                        ),
                    beforeContentPadding = config.beforeContentPaddingPx,
                    afterContentPadding = config.afterContentPaddingPx,
                    beforeAutoCenteringPadding =
                        calculateTopAutoCenteringPaddingPx(
                            config,
                            visibleItemsInfo,
                            totalItemsCount,
                        ),
                    afterAutoCenteringPadding =
                        calculateBottomAutoCenteringPaddingPx(
                            config,
                            visibleItemsInfo,
                            totalItemsCount,
                        ),
                    readyForInitialScroll = readyForInitialScroll,
                    initialized = initialized,
                    anchorType = config.anchorType,
                )
            }
        }

The object of ScalingLazyListLayoutInfo calculated during the last layout pass. For example, you can use it to calculate what items are currently visible.

Content updated: