androidx.compose.ui.layout

Interfaces

ContentScale

Represents a rule to apply to scale a source rectangle to be inscribed into a destination

IntrinsicMeasurable

A part of the composition that can be measured.

LayoutCoordinates

A holder of the measured bounds for the layout (MeasureBox).

LayoutIdParentData

Can be implemented by values used as parent data to make them usable as tags.

Classes

FixedScale

ContentScale implementation that always scales the dimension by the provided fixed floating point value

IntrinsicMeasureScope

The receiver scope of a layout's intrinsic measurements lambdas.

Measured

Read-only wrapper over Placeable that exposes the measurement result with no placing ability.

SubcomposeMeasureScope

The receiver scope of a SubcomposeLayout's measure lambda which adds ability to dynamically subcompose a content during the measuring on top of the features provided by MeasureScope.

Type-aliases

IntrinsicMeasureBlock

A function for performing intrinsic measurement.

Annotations

ExperimentalSubcomposeLayoutApi

Top-level functions summary

Unit

Analogue of Layout which allows to subcompose the actual content during the measuring stage for example to use the values calculated during the measurement as params for the composition of the children.

Extension functions summary

For Modifier
Modifier

Tag the element with id to identify the element within its parent.

Extension properties summary

For LayoutCoordinates
Rect

Returns the bounding box of the child in the parent's content area, including any clipping done with respect to the parent.

Rect

The boundaries of this layout inside the root composable.

Rect

The global boundaries of this layout inside.

Offset

The global position of this layout.

Offset

Returns the position of the top-left in the parent's content area or (0, 0) for the root.

Offset

The position of this layout inside the root composable.

For Measurable
Any?

Retrieves the tag associated to a composable with the Modifier.layoutId modifier.

Top-level functions

SubcomposeLayout

@Composable fun <T> SubcomposeLayout(
    modifier: Modifier = Modifier,
    measureBlock: SubcomposeMeasureScope<T>.(Constraints) -> MeasureScope.MeasureResult
): Unit

Analogue of Layout which allows to subcompose the actual content during the measuring stage for example to use the values calculated during the measurement as params for the composition of the children.

Possible use cases:

  • You need to know the constraints passed by the parent during the composition and can't solve your use case with just custom Layout or LayoutModifier. See WithConstraints.
  • You want to use the size of one child during the composition of the second child. Example is using the sizes of the tabs in TabRow as a input in tabs indicator composable
  • You want to compose your items lazily based on the available size. For example you have a list of 100 items and instead of composing all of them you only compose the ones which are currently visible(say 5 of them) and compose next items when the component is scrolled.
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.unit.IntSize

SubcomposeLayout<SlotsEnum> { constraints ->
    val mainPlaceables = subcompose(SlotsEnum.Main, mainContent).map {
        it.measure(constraints)
    }
    val maxSize = mainPlaceables.fold(IntSize.Zero) { currentMax, placeable ->
        IntSize(
            width = maxOf(currentMax.width, placeable.width),
            height = maxOf(currentMax.height, placeable.height)
        )
    }
    layout(maxSize.width, maxSize.height) {
        mainPlaceables.forEach { it.placeRelative(0, 0) }
        subcompose(SlotsEnum.Dependent) {
            dependentContent(maxSize)
        }.forEach {
            it.measure(constraints).placeRelative(0, 0)
        }
    }
}
Parameters
modifier: Modifier = Modifier Modifier to apply for the layout.
measureBlock: SubcomposeMeasureScope<T>.(Constraints) -> MeasureScope.MeasureResult Measure block which provides ability to subcompose during the measuring.

Extension functions

layoutId

@Stable fun Modifier.layoutId(id: Any): Modifier

Tag the element with id to identify the element within its parent.

Example usage:

import androidx.compose.foundation.Box
import androidx.compose.ui.Layout
import androidx.compose.ui.layout
import androidx.compose.ui.layout.layoutId

Layout({
    // Here the Containers are only needed to apply the modifiers. You could use the
    // modifier on header and footer directly if they are composables accepting modifiers.
    Box(Modifier.layoutId("header"), children = header)
    Box(Modifier.layoutId("footer"), children = footer)
}) { measurables, constraints ->
    val placeables = measurables.map { measurable ->
        when (measurable.id) {
            // You should use appropriate constraints. Here we measure fake constraints.
            "header" -> measurable.measure(Constraints.fixed(100, 100))
            "footer" -> measurable.measure(constraints)
            else -> error("Unexpected tag")
        }
    }
    // Size should be derived from children measured sizes on placeables,
    // but this is simplified for the purposes of the example.
    layout(100, 100) {
        placeables.forEach { it.placeRelative(0, 0) }
    }
}

Extension properties

boundsInParent

val LayoutCoordinates.boundsInParent: Rect

Returns the bounding box of the child in the parent's content area, including any clipping done with respect to the parent. For the root, the bounds is positioned at (0, 0) and sized to the size of the root.

boundsInRoot

val LayoutCoordinates.boundsInRoot: Rect

The boundaries of this layout inside the root composable.

globalBounds

val LayoutCoordinates.globalBounds: Rect

The global boundaries of this layout inside.

globalPosition

inline val LayoutCoordinates.globalPosition: Offset

The global position of this layout.

id

val Measurable.id: Any?

Retrieves the tag associated to a composable with the Modifier.layoutId modifier. For a parent data value to be returned by this property when not using the Modifier.layoutId modifier, the parent data value should implement the LayoutIdParentData interface.

Example usage:

import androidx.compose.foundation.Box
import androidx.compose.ui.Layout
import androidx.compose.ui.layout
import androidx.compose.ui.layout.layoutId

Layout({
    // Here the Containers are only needed to apply the modifiers. You could use the
    // modifier on header and footer directly if they are composables accepting modifiers.
    Box(Modifier.layoutId("header"), children = header)
    Box(Modifier.layoutId("footer"), children = footer)
}) { measurables, constraints ->
    val placeables = measurables.map { measurable ->
        when (measurable.id) {
            // You should use appropriate constraints. Here we measure fake constraints.
            "header" -> measurable.measure(Constraints.fixed(100, 100))
            "footer" -> measurable.measure(constraints)
            else -> error("Unexpected tag")
        }
    }
    // Size should be derived from children measured sizes on placeables,
    // but this is simplified for the purposes of the example.
    layout(100, 100) {
        placeables.forEach { it.placeRelative(0, 0) }
    }
}

positionInParent

val LayoutCoordinates.positionInParent: Offset

Returns the position of the top-left in the parent's content area or (0, 0) for the root.

positionInRoot

inline val LayoutCoordinates.positionInRoot: Offset

The position of this layout inside the root composable.