# LazyLayoutPrefetchState

Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState.kt+class:androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState) Added in [1.2.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.2.0) Common/AllAndroid/JVM
- Cmn

  ```
  class LazyLayoutPrefetchState
  ```

*** ** * ** ***

State for lazy items prefetching, used by lazy layouts to instruct the prefetcher.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.layout.LazyLayout
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.dp

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)
            }
        }
    }
}
```

## Summary

| ### Nested types |
|---|
| `sealed interface LazyLayoutPrefetchState.PrefetchHandle` A handle to control some aspects of the prefetch request. |
| `sealed interface LazyLayoutPrefetchState.PrefetchResultScope` A scope for `schedulePrecompositionAndPremeasure` callbacks. |

| ### Public constructors |
|---|---|
| `LazyLayoutPrefetchState()` | Cmn |
| `@ExperimentalFoundationApi LazyLayoutPrefetchState(onNestedPrefetch: (NestedPrefetchScope.() -> Unit)?)` State for lazy items prefetching, used by lazy layouts to instruct the prefetcher. | Cmn |
| `@ExperimentalFoundationApi [LazyLayoutPrefetchState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState#LazyLayoutPrefetchState(androidx.compose.foundation.lazy.layout.PrefetchScheduler,kotlin.Function1))( prefetchScheduler: PrefetchScheduler?, onNestedPrefetch: (NestedPrefetchScope.() -> Unit)? )` **This function is deprecated.** Please use overload without Prefetch Scheduler. | Cmn |

| ### Public functions |
|---|---|---|
| `LazyLayoutPrefetchState.PrefetchHandle` | `schedulePrecomposition(index: @IntRange(from = 0) Int)` Schedules precomposition for the new item. | Cmn |
| `LazyLayoutPrefetchState.PrefetchHandle` | `schedulePrecompositionAndPremeasure( index: @IntRange(from = 0) Int, constraints: Constraints, onItemPremeasured: (LazyLayoutPrefetchState.PrefetchResultScope.() -> Unit)? )` Schedules precomposition and premeasure for the new item. | Cmn |

## Public constructors

### LazyLayoutPrefetchState

Cmn Added in [1.2.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.2.0)

```
LazyLayoutPrefetchState()
```

### LazyLayoutPrefetchState

Cmn Added in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.9.0)

```
@ExperimentalFoundationApi
LazyLayoutPrefetchState(onNestedPrefetch: (NestedPrefetchScope.() -> Unit)? = null)
```

State for lazy items prefetching, used by lazy layouts to instruct the prefetcher.

| Parameters |
|---|---|
| `onNestedPrefetch: (NestedPrefetchScope.() -> Unit)? = null` | a callback which will be invoked when this LazyLayout is prefetched in context of a parent LazyLayout, giving a chance to recursively prefetch its own children. See `NestedPrefetchScope`. |

### LazyLayoutPrefetchState

Cmn Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.7.0) Deprecated in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.9.0)

```
@ExperimentalFoundationApi
[LazyLayoutPrefetchState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState#LazyLayoutPrefetchState(androidx.compose.foundation.lazy.layout.PrefetchScheduler,kotlin.Function1))(
    prefetchScheduler: PrefetchScheduler? = null,
    onNestedPrefetch: (NestedPrefetchScope.() -> Unit)? = null
)
```

> [!CAUTION]
> **This function is deprecated.**   
> Please use overload without Prefetch Scheduler.

State for lazy items prefetching, used by lazy layouts to instruct the prefetcher.

| Parameters |
|---|---|
| `prefetchScheduler: PrefetchScheduler? = null` | the `PrefetchScheduler` implementation to use to execute prefetch requests. If null is provided, the default `PrefetchScheduler` for the platform will be used. |
| `onNestedPrefetch: (NestedPrefetchScope.() -> Unit)? = null` | a callback which will be invoked when this LazyLayout is prefetched in context of a parent LazyLayout, giving a chance to recursively prefetch its own children. See `NestedPrefetchScope`. |

## Public functions

### schedulePrecomposition

Cmn Added in [1.9.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation.md.txt#1.9.0)

```
fun schedulePrecomposition(index: @IntRange(from = 0) Int): LazyLayoutPrefetchState.PrefetchHandle
```

Schedules precomposition for the new item. If you also want to premeasure the item please use `schedulePrecompositionAndPremeasure` instead. This function should only be called once per item. If the item has already been composed at the time this request executes, either from a previous call to this function or because the item is already visible, this request should have no meaningful effect.

| Parameters |
|---|---|
| `index: @IntRange(from = 0) Int` | item index to prefetch. |

| Returns |
|---|---|
| `LazyLayoutPrefetchState.PrefetchHandle` | A `PrefetchHandle` which can be used to control the lifecycle of the prefetch request. Use `PrefetchHandle.cancel` to cancel the request or `PrefetchHandle.markAsUrgent` to mark the request as urgent. |

### schedulePrecompositionAndPremeasure

Cmn

```
fun schedulePrecompositionAndPremeasure(
    index: @IntRange(from = 0) Int,
    constraints: Constraints,
    onItemPremeasured: (LazyLayoutPrefetchState.PrefetchResultScope.() -> Unit)? = null
): LazyLayoutPrefetchState.PrefetchHandle
```

Schedules precomposition and premeasure for the new item. This should be used instead of `schedulePrecomposition` if you also want to premeasure the item. This function should only be called once per item. If the item has already been composed / measured at the time this request executes, either from a previous call to this function or because the item is already visible, this request should have no meaningful effect.

| Parameters |
|---|---|
| `index: @IntRange(from = 0) Int` | item index to prefetch. |
| `constraints: Constraints` | `Constraints` to use for premeasuring. |
| `onItemPremeasured: (LazyLayoutPrefetchState.PrefetchResultScope.() -> Unit)? = null` | This callback is called when the item premeasuring is finished. If the request is canceled or no measuring is performed this callback won't be called. Use `PrefetchResultScope.getSize` to get the item's size. |

| Returns |
|---|---|
| `LazyLayoutPrefetchState.PrefetchHandle` | A `PrefetchHandle` which can be used to control the lifecycle of the prefetch request. Use `PrefetchHandle.cancel` to cancel the request or `PrefetchHandle.markAsUrgent` to mark the request as urgent. |