MeasureScope

Known direct subclasses
ApproachMeasureScope

ApproachMeasureScope provides access to lookahead results to allow ApproachLayoutModifierNode to leverage lookahead results to define how measurements and placements approach their destination.

LazyLayoutMeasureScope

The receiver scope of a LazyLayout's measure lambda.

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.


The receiver scope of a layout's measure lambda. The return value of the measure lambda is MeasureResult, which should be returned by layout

Summary

Public functions

open MeasureResult
layout(
    width: Int,
    height: Int,
    alignmentLines: Map<AlignmentLineInt>,
    placementBlock: Placeable.PlacementScope.() -> Unit
)

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic.

Cmn
open MeasureResult
layout(
    width: Int,
    height: Int,
    alignmentLines: Map<AlignmentLineInt>,
    rulers: (RulerScope.() -> Unit)?,
    placementBlock: Placeable.PlacementScope.() -> Unit
)

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic.

Cmn
open MeasureResult
layout(
    width: Int,
    height: Int,
    isRulerProvided: (Ruler) -> Boolean,
    rulerProvider: RulerScope.(Ruler) -> Unit,
    alignmentLines: Map<AlignmentLineInt>,
    placementBlock: Placeable.PlacementScope.() -> Unit
)

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic.

Cmn

Inherited functions

From androidx.compose.ui.unit.Density
open Int

Convert Dp to Int by rounding

Cmn
open Int

Convert Sp to Int by rounding

Cmn
open Dp

Convert an Int pixel value to Dp.

Cmn
open Dp

Convert a Float pixel value to a Dp

Cmn
open DpSize

Convert a Size to a DpSize.

Cmn
open Float

Convert Dp to pixels.

Cmn
open Float

Convert Sp to pixels.

Cmn
open Rect

Convert a DpRect to a Rect.

Cmn
open Size

Convert a DpSize to a Size.

Cmn
open TextUnit

Convert an Int pixel value to Sp.

Cmn
open TextUnit

Convert a Float pixel value to a Sp

Cmn
From androidx.compose.ui.unit.FontScaling
Dp

Convert Sp to Dp.

Cmn
TextUnit

Convert Dp to Sp.

Cmn

Inherited properties

From androidx.compose.ui.unit.Density
Float

The logical density of the display.

Cmn
From androidx.compose.ui.unit.FontScaling
Float

Current user preference for the scaling factor for fonts.

Cmn
From androidx.compose.ui.layout.IntrinsicMeasureScope
open Boolean

This indicates whether the ongoing measurement is for lookahead pass.

Cmn
LayoutDirection

The LayoutDirection of the Layout or LayoutModifier using the measure scope to measure their children.

Cmn

Public functions

layout

open fun layout(
    width: Int,
    height: Int,
    alignmentLines: Map<AlignmentLineInt> = emptyMap(),
    placementBlock: Placeable.PlacementScope.() -> Unit
): MeasureResult

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic. The placementBlock is a lambda used for positioning children. Placeable.placeAt should be called on children inside placementBlock. The alignmentLines can be used by the parent layouts to decide layout, and can be queried using the Placeable.get operator. Note that alignment lines will be inherited by parent layouts, such that indirect parents will be able to query them as well.

Parameters
width: Int

the measured width of the layout

height: Int

the measured height of the layout

alignmentLines: Map<AlignmentLineInt> = emptyMap()

the alignment lines defined by the layout

placementBlock: Placeable.PlacementScope.() -> Unit

block defining the children positioning of the current layout

layout

open fun layout(
    width: Int,
    height: Int,
    alignmentLines: Map<AlignmentLineInt> = emptyMap(),
    rulers: (RulerScope.() -> Unit)? = null,
    placementBlock: Placeable.PlacementScope.() -> Unit
): MeasureResult

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic. The placementBlock is a lambda used for positioning children. Placeable.placeAt should be called on children inside placementBlock. The alignmentLines can be used by the parent layouts to decide layout, and can be queried using the Placeable.get operator. Note that alignment lines will be inherited by parent layouts, such that indirect parents will be able to query them as well.

Parameters
width: Int

the measured width of the layout

height: Int

the measured height of the layout

alignmentLines: Map<AlignmentLineInt> = emptyMap()

the alignment lines defined by the layout

rulers: (RulerScope.() -> Unit)? = null

a method to set Ruler values used by all placed children

placementBlock: Placeable.PlacementScope.() -> Unit

block defining the children positioning of the current layout

layout

open fun layout(
    width: Int,
    height: Int,
    isRulerProvided: (Ruler) -> Boolean,
    rulerProvider: RulerScope.(Ruler) -> Unit,
    alignmentLines: Map<AlignmentLineInt> = emptyMap(),
    placementBlock: Placeable.PlacementScope.() -> Unit
): MeasureResult

Sets the size and alignment lines of the measured layout, as well as the positioning block that defines the children positioning logic. The placementBlock is a lambda used for positioning children. Placeable.placeAt should be called on children inside placementBlock. The alignmentLines can be used by the parent layouts to decide layout, and can be queried using the Placeable.get operator. Note that alignment lines will be inherited by parent layouts, such that indirect parents will be able to query them as well.

Use this version when providing the Rulers is expensive and should only be done when needed.

import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.HorizontalRuler
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.VerticalRuler
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.positionOnScreen
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Constraints

// Position of the left side of the screen
val ScreenLeftRuler = VerticalRuler()
// Position of the top of the screen
val ScreenTopRuler = HorizontalRuler()
// Position of the right side of the screen
val ScreenRightRuler = VerticalRuler()
// Position of the bottom of the screen
val ScreenBottomRuler = HorizontalRuler()

class ScreenRulerNode :
    Modifier.Node(), LayoutModifierNode, CompositionLocalConsumerModifierNode {
    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints,
    ): MeasureResult {
        val placeable = measurable.measure(constraints)
        return layout(
            placeable.width,
            placeable.height,
            isRulerProvided = { ruler ->
                ruler === ScreenLeftRuler ||
                    ruler === ScreenTopRuler ||
                    ruler === ScreenRightRuler ||
                    ruler === ScreenBottomRuler
            },
            rulerProvider = {
                // Because these rulers are updated when the View or Window moves, this may be
                // expensive if the ComposeView is in a RecyclerView, for example. If no
                // content has requested a screen position ruler, this won't be called and
                // the calculation can be avoided.
                val positionOnScreen = coordinates.positionOnScreen()

                // Once we've calculated the position on screen, we may as well provide
                // all values since it doesn't cost much to provide everything. The developer
                // is likely to request multiple values if they request one.
                ScreenLeftRuler provides -positionOnScreen.x
                ScreenTopRuler provides -positionOnScreen.y

                // We have to find the screen size from the DisplayMetrics
                val displayMetrics = currentValueOf(LocalContext).resources.displayMetrics
                val screenHeight = displayMetrics.heightPixels
                val screenWidth = displayMetrics.widthPixels
                ScreenRightRuler provides screenWidth - positionOnScreen.x
                ScreenBottomRuler provides screenHeight - positionOnScreen.y
            },
        ) {
            placeable.place(0, 0)
        }
    }
}
Parameters
width: Int

the measured width of the layout

height: Int

the measured height of the layout

isRulerProvided: (Ruler) -> Boolean

Works in conjunction with rulerProvider to provide Ruler values individually. A return value of true indicates that rulerProvider might be able to provide a value for the passed-in Ruler. A value of false means it can never provide the value.

rulerProvider: RulerScope.(Ruler) -> Unit

A lambda that can provide Ruler values. When isRulerProvided returns true for a Ruler, rulerProvider will be called to provide its value. rulerProvider can choose not to provide the value if it isn't available. It can also provide more Ruler values if it is convenient to provide them. For example, it may be convenient to provide all values for a RectRulers when one is provided.

alignmentLines: Map<AlignmentLineInt> = emptyMap()

the alignment lines defined by the layout

placementBlock: Placeable.PlacementScope.() -> Unit

block defining the children positioning of the current layout