Composable Function

Layout

Layout is the main core component for layout.

LayoutUsage

@Sampled
@Composable
fun LayoutUsage(content: @Composable () -> Unit) {
    // 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)
            }
        }
    }
}

LayoutWithProvidedIntrinsicsUsage

@Sampled
@Composable
fun LayoutWithProvidedIntrinsicsUsage(content: @Composable () -> Unit) {
    // 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.maxIntrinsicWidth(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)
}

LayoutWithMultipleContentsUsage

@Sampled
@Composable
fun LayoutWithMultipleContentsUsage(
    content1: @Composable () -> Unit,
    content2: @Composable () -> Unit,
) {
    // 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
            }
        }
    }
}
Jetpack Compose beyond MaterialFree components, screens and templates for apps that don’t look like Google’s. Copy them into your app, or let your coding agent add them.Browse for free

Content updated: