{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

LayoutKt

public final class LayoutKt


Summary

Public methods

static final void

Layout is the main core component for layout for "leaf" nodes.

static final void
@UiComposable
@Composable
Layout(
    @Composable @UiComposable @NonNull Function0<Unit> content,
    @NonNull Modifier modifier,
    @NonNull MeasurePolicy measurePolicy
)

Layout is the main core component for layout.

static final void
@UiComposable
@Composable
Layout(
    @NonNull List<@Composable @UiComposable @NonNull Function0<Unit>> contents,
    @NonNull Modifier modifier,
    @NonNull MultiContentMeasurePolicy measurePolicy
)

Layout is the main core component for layout.

static final void
@Composable
@UiComposable
MultiMeasureLayout(
    @NonNull Modifier modifier,
    @Composable @UiComposable @NonNull Function0<Unit> content,
    @NonNull MeasurePolicy measurePolicy
)

This method is deprecated. This API is unsafe for UI performance at scale - using it incorrectly will lead to exponential performance issues.

Public methods

Layout

@Composable
@UiComposable
public static final void Layout(@NonNull Modifier modifier, @NonNull MeasurePolicy measurePolicy)

Layout is the main core component for layout for "leaf" nodes. It can be used to measure and position zero children.

The measurement, layout and intrinsic measurement behaviours of this layout will be defined by the measurePolicy instance. See MeasurePolicy for more details.

For a composable able to define its content according to the incoming constraints, see androidx.compose.foundation.layout.BoxWithConstraints.

Example usage:

import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints

// We build a layout that will occupy twice as much space as its children,
// and will position them to be bottom right aligned.
Layout(content) { measurables, constraints ->
    // measurables contains one element corresponding to each of our layout children.
    // constraints are the constraints that our parent is currently measuring us with.
    val childConstraints = Constraints(
        minWidth = constraints.minWidth / 2,
        minHeight = constraints.minHeight / 2,
        maxWidth = if (constraints.hasBoundedWidth) {
            constraints.maxWidth / 2
        } else {
            Constraints.Infinity
        },
        maxHeight = if (constraints.hasBoundedHeight) {
            constraints.maxHeight / 2
        } else {
            Constraints.Infinity
        }
    )
    // We measure the children with half our constraints, to ensure we can be double
    // the size of the children.
    val placeables = measurables.map { it.measure(childConstraints) }
    val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
    val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
    // We call layout to set the size of the current layout and to provide the positioning
    // of the children. The children are placed relative to the current layout place.
    layout(layoutWidth, layoutHeight) {
        placeables.forEach {
            it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
        }
    }
}

Example usage with custom intrinsic measurements:

import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints

// We build a layout that will occupy twice as much space as its children,
// and will position them to be bottom right aligned.
val measurePolicy = object : MeasurePolicy {
    override fun MeasureScope.measure(
        measurables: List<Measurable>,
        constraints: Constraints
    ): MeasureResult {
        // measurables contains one element corresponding to each of our layout children.
        // constraints are the constraints that our parent is currently measuring us with.
        val childConstraints = Constraints(
            minWidth = constraints.minWidth / 2,
            minHeight = constraints.minHeight / 2,
            maxWidth = if (constraints.hasBoundedWidth) {
                constraints.maxWidth / 2
            } else {
                Constraints.Infinity
            },
            maxHeight = if (constraints.hasBoundedHeight) {
                constraints.maxHeight / 2
            } else {
                Constraints.Infinity
            }
        )
        // We measure the children with half our constraints, to ensure we can be double
        // the size of the children.
        val placeables = measurables.map { it.measure(childConstraints) }
        val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
        val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
        // We call layout to set the size of the current layout and to provide the positioning
        // of the children. The children are placed relative to the current layout place.
        return layout(layoutWidth, layoutHeight) {
            placeables.forEach {
                it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
            }
        }
    }

    // The min intrinsic width of this layout will be twice the largest min intrinsic
    // width of a child. Note that we call minIntrinsicWidth with h / 2 for children,
    // since we should be double the size of the children.
    override fun IntrinsicMeasureScope.minIntrinsicWidth(
        measurables: List<IntrinsicMeasurable>,
        height: Int
    ) = (measurables.map { it.minIntrinsicWidth(height / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.minIntrinsicHeight(
        measurables: List<IntrinsicMeasurable>,
        width: Int
    ) = (measurables.map { it.minIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
        measurables: List<IntrinsicMeasurable>,
        height: Int
    ) = (measurables.map { it.maxIntrinsicHeight(height / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
        measurables: List<IntrinsicMeasurable>,
        width: Int
    ) = (measurables.map { it.maxIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2
}

Layout(content = content, measurePolicy = measurePolicy)
Parameters
@NonNull Modifier modifier

Modifiers to be applied to the layout.

@NonNull MeasurePolicy measurePolicy

The policy defining the measurement and positioning of the layout.

Layout

@UiComposable
@Composable
public static final void Layout(
    @Composable @UiComposable @NonNull Function0<Unit> content,
    @NonNull Modifier modifier,
    @NonNull MeasurePolicy measurePolicy
)

Layout is the main core component for layout. It can be used to measure and position zero or more layout children.

The measurement, layout and intrinsic measurement behaviours of this layout will be defined by the measurePolicy instance. See MeasurePolicy for more details.

For a composable able to define its content according to the incoming constraints, see androidx.compose.foundation.layout.BoxWithConstraints.

Example usage:

import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints

// We build a layout that will occupy twice as much space as its children,
// and will position them to be bottom right aligned.
Layout(content) { measurables, constraints ->
    // measurables contains one element corresponding to each of our layout children.
    // constraints are the constraints that our parent is currently measuring us with.
    val childConstraints = Constraints(
        minWidth = constraints.minWidth / 2,
        minHeight = constraints.minHeight / 2,
        maxWidth = if (constraints.hasBoundedWidth) {
            constraints.maxWidth / 2
        } else {
            Constraints.Infinity
        },
        maxHeight = if (constraints.hasBoundedHeight) {
            constraints.maxHeight / 2
        } else {
            Constraints.Infinity
        }
    )
    // We measure the children with half our constraints, to ensure we can be double
    // the size of the children.
    val placeables = measurables.map { it.measure(childConstraints) }
    val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
    val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
    // We call layout to set the size of the current layout and to provide the positioning
    // of the children. The children are placed relative to the current layout place.
    layout(layoutWidth, layoutHeight) {
        placeables.forEach {
            it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
        }
    }
}

Example usage with custom intrinsic measurements:

import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints

// We build a layout that will occupy twice as much space as its children,
// and will position them to be bottom right aligned.
val measurePolicy = object : MeasurePolicy {
    override fun MeasureScope.measure(
        measurables: List<Measurable>,
        constraints: Constraints
    ): MeasureResult {
        // measurables contains one element corresponding to each of our layout children.
        // constraints are the constraints that our parent is currently measuring us with.
        val childConstraints = Constraints(
            minWidth = constraints.minWidth / 2,
            minHeight = constraints.minHeight / 2,
            maxWidth = if (constraints.hasBoundedWidth) {
                constraints.maxWidth / 2
            } else {
                Constraints.Infinity
            },
            maxHeight = if (constraints.hasBoundedHeight) {
                constraints.maxHeight / 2
            } else {
                Constraints.Infinity
            }
        )
        // We measure the children with half our constraints, to ensure we can be double
        // the size of the children.
        val placeables = measurables.map { it.measure(childConstraints) }
        val layoutWidth = (placeables.maxByOrNull { it.width }?.width ?: 0) * 2
        val layoutHeight = (placeables.maxByOrNull { it.height }?.height ?: 0) * 2
        // We call layout to set the size of the current layout and to provide the positioning
        // of the children. The children are placed relative to the current layout place.
        return layout(layoutWidth, layoutHeight) {
            placeables.forEach {
                it.placeRelative(layoutWidth - it.width, layoutHeight - it.height)
            }
        }
    }

    // The min intrinsic width of this layout will be twice the largest min intrinsic
    // width of a child. Note that we call minIntrinsicWidth with h / 2 for children,
    // since we should be double the size of the children.
    override fun IntrinsicMeasureScope.minIntrinsicWidth(
        measurables: List<IntrinsicMeasurable>,
        height: Int
    ) = (measurables.map { it.minIntrinsicWidth(height / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.minIntrinsicHeight(
        measurables: List<IntrinsicMeasurable>,
        width: Int
    ) = (measurables.map { it.minIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.maxIntrinsicWidth(
        measurables: List<IntrinsicMeasurable>,
        height: Int
    ) = (measurables.map { it.maxIntrinsicHeight(height / 2) }.maxByOrNull { it } ?: 0) * 2

    override fun IntrinsicMeasureScope.maxIntrinsicHeight(
        measurables: List<IntrinsicMeasurable>,
        width: Int
    ) = (measurables.map { it.maxIntrinsicHeight(width / 2) }.maxByOrNull { it } ?: 0) * 2
}

Layout(content = content, measurePolicy = measurePolicy)
Parameters
@Composable @UiComposable @NonNull Function0<Unit> content

The children composable to be laid out.

@NonNull Modifier modifier

Modifiers to be applied to the layout.

@NonNull MeasurePolicy measurePolicy

The policy defining the measurement and positioning of the layout.

Layout

@UiComposable
@Composable
public static final void Layout(
    @NonNull List<@Composable @UiComposable @NonNull Function0<Unit>> contents,
    @NonNull Modifier modifier,
    @NonNull MultiContentMeasurePolicy measurePolicy
)

Layout is the main core component for layout. It can be used to measure and position zero or more layout children.

This overload accepts a list of multiple composable content lambdas, which allows treating measurables put into different content lambdas differently - measure policy will provide a list of lists of Measurables, not just a single list. Such list has the same size as the list of contents passed into Layout and contains the list of measurables of the corresponding content lambda in the same order.

Note that layouts emitted as part of all contents lambdas will be added as a direct children for this Layout. This means that if you set a custom z index on some children, the drawing order will be calculated as if they were all provided as part of one lambda.

Example usage:

import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.layout

// We can provide pass a list of two composable lambdas in order to be able to treat
// measureables from each lambda differently.
Layout(listOf(content1, content2)) { (content1Measurables, content2Measurables), constraints ->
    val content1Placeables = content1Measurables.map { it.measure(constraints) }
    val content2Placeables = content2Measurables.map { it.measure(constraints) }
    layout(constraints.maxWidth, constraints.maxHeight) {
        var currentX = 0
        var currentY = 0
        var currentMaxHeight = 0
        // we place placeables from content1 as a first line
        content1Placeables.forEach {
            it.place(currentX, currentY)
            currentX += it.width
            currentMaxHeight = maxOf(currentMaxHeight, it.height)
        }
        currentX = 0
        currentY = currentMaxHeight
        // and placeables from content2 composable as a second line
        content2Placeables.forEach {
            it.place(currentX, currentY)
            currentX += it.width
        }
    }
}
Parameters
@NonNull List<@Composable @UiComposable @NonNull Function0<Unit>> contents

The list of children composable contents to be laid out.

@NonNull Modifier modifier

Modifiers to be applied to the layout.

@NonNull MultiContentMeasurePolicy measurePolicy

The policy defining the measurement and positioning of the layout.

See also
Layout

for a simpler use case when you have only one content lambda.

MultiMeasureLayout

@Composable
@UiComposable
public static final void MultiMeasureLayout(
    @NonNull Modifier modifier,
    @Composable @UiComposable @NonNull Function0<Unit> content,
    @NonNull MeasurePolicy measurePolicy
)