State for lazy items prefetching, used by lazy layouts to instruct the prefetcher.
LazyLayoutPrefetchStateSample
@Preview
@Composable
fun LazyLayoutPrefetchStateSample() {
val items = remember { (0..100).toList().map { it.toString() } }
var currentHandle = remember<LazyLayoutPrefetchState.PrefetchHandle?> { null }
val prefetchState = remember { LazyLayoutPrefetchState() }
// 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])
}
}
}
}
}
Column {
Button(onClick = { currentHandle = prefetchState.schedulePrecomposition(10) }) {
Text(text = "Prefetch Item 10")
}
Button(onClick = { currentHandle?.cancel() }) { Text(text = "Cancel Prefetch") }
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)
}
}
}
}
}