LazyLayout
Common
Component in Compose Foundation
A layout that only composes and lays out currently needed items. Can be used to build efficient scrollable layouts.
Last updated:
Installation
dependencies {
implementation("androidx.compose.foundation:foundation:1.9.0-alpha04")
}
Overloads
@Deprecated("Please use overload with LazyLayoutMeasurePolicy", level = DeprecationLevel.HIDDEN)
@ExperimentalFoundationApi
@Composable
fun LazyLayout(
itemProvider: () -> LazyLayoutItemProvider,
modifier: Modifier = Modifier,
prefetchState: LazyLayoutPrefetchState? = null,
measurePolicy: LazyLayoutMeasureScope.(Constraints) -> MeasureResult,
)
Parameters
name | description |
---|---|
itemProvider | lambda producing an item provider containing all the needed info about the items which could be used to compose and measure items as part of [measurePolicy]. |
modifier | to apply on the layout |
prefetchState | allows to schedule items for prefetching |
measurePolicy | Measure policy which allows to only compose and measure needed items. |
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LazyLayout(
itemProvider: () -> LazyLayoutItemProvider,
modifier: Modifier = Modifier,
prefetchState: LazyLayoutPrefetchState? = null,
measurePolicy: LazyLayoutMeasurePolicy,
)
Parameters
name | description |
---|---|
itemProvider | lambda producing an item provider containing all the needed info about the items which could be used to compose and measure items as part of [measurePolicy]. |
modifier | to apply on the layout |
prefetchState | allows to schedule items for prefetching |
measurePolicy | Measure policy which allows to only compose and measure needed items. |
Code Example
LazyLayoutSample
/** A simple Layout that will place items right to left with scrolling support. */
@Preview
@Composable
fun LazyLayoutSample() {
val items = remember { (0..100).toList().map { it.toString() } }
// Create an item provider
val itemProvider = remember {
{
object : LazyLayoutItemProvider {
override val itemCount: Int
get() = 100
@Composable
override fun Item(index: Int, key: Any) {
Box(
modifier =
Modifier.width(100.dp)
.height(100.dp)
.background(color = if (index % 2 == 0) Color.Red else Color.Green)
) {
Text(text = items[index])
}
}
}
}
}
LazyLayout(modifier = Modifier.size(500.dp), itemProvider = itemProvider) { constraints ->
// plug the measure policy, this is how we create and layout items.
val placeablesCache = mutableListOf<Pair<Placeable, Int>>()
fun Placeable.mainAxisSize() = width
fun Placeable.crossAxisSize() = height
val childConstraints =
Constraints(maxWidth = Constraints.Infinity, maxHeight = constraints.maxHeight)
var currentItemIndex = 0
var crossAxisSize = 0
var mainAxisSize = 0
// measure items until we either fill in the space or run out of items.
while (mainAxisSize < constraints.maxWidth && currentItemIndex < items.size) {
val itemPlaceables = compose(currentItemIndex).map { it.measure(childConstraints) }
for (item in itemPlaceables) {
// save placeable to be placed later.
placeablesCache.add(item to mainAxisSize)
mainAxisSize += item.mainAxisSize() // item size contributes to main axis size
// cross axis size will the size of tallest/widest item
crossAxisSize = maxOf(crossAxisSize, item.crossAxisSize())
}
currentItemIndex++
}
val layoutWidth = minOf(mainAxisSize, constraints.maxHeight)
val layoutHeight = crossAxisSize
layout(layoutWidth, layoutHeight) {
// since this is a linear list all items are placed on the same cross-axis position
for ((placeable, position) in placeablesCache) {
placeable.place(position, 0)
}
}
}
}