Placeable.PlacementScope
-
Cmn
@PlacementScopeMarker
abstract class Placeable.PlacementScope : Density
Receiver scope that permits explicit placement of a Placeable.
While a Placeable may be placed at any time, this explicit receiver scope is used to discourage placement outside of MeasureScope.layout positioning blocks. This permits Compose UI to perform additional layout optimizations allowing repositioning a Placeable without remeasuring its original Measurable if factors contributing to its potential measurement have not changed. The scope also allows automatic mirroring of children positions in RTL layout direction contexts using the placeRelative methods available in the scope. If the automatic mirroring is not desired, place should be used instead.
Summary
Public constructors |
|
|---|---|
|
Cmn
|
Public functions |
||
|---|---|---|
open Float |
Returns the value for this |
Cmn
|
Unit |
Place a |
Cmn
|
Unit |
Place a |
Cmn
|
Unit |
Placeable.placeRelative(position: IntOffset, zIndex: Float)Place a |
Cmn
|
Unit |
Placeable.placeRelative(x: Int, y: Int, zIndex: Float)Place a |
Cmn
|
Unit |
Placeable.placeRelativeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeRelativeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeRelativeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeRelativeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeWithLayer(Place a |
Cmn
|
Unit |
Placeable.placeWithLayer(Place a |
Cmn
|
Unit |
withMotionFrameOfReferencePlacement(block: Placeable.PlacementScope.() -> Unit)Placement done under |
Cmn
|
Public properties |
||
|---|---|---|
open LayoutCoordinates? |
The |
Cmn
|
open Float |
The logical density of the display. |
Cmn
|
open Float |
Current user preference for the scaling factor for fonts. |
Cmn
|
Protected properties |
||
|---|---|---|
abstract LayoutDirection |
Keeps the layout direction of the parent of the placeable that is being places using current |
Cmn
|
abstract Int |
Keeps the parent layout node's width to make the automatic mirroring of the position in RTL environment. |
Cmn
|
Extension functions |
||
|---|---|---|
List<RectRulers> |
Returns a List of |
Cmn
|
Inherited functions |
|||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|||||||||||||||||||||||||||||||||
Public constructors
Public functions
current
open fun Ruler.current(defaultValue: Float): Float
Returns the value for this Ruler or defaultValue if it wasn't provided. Ruler values are unavailable while calculating AlignmentLines.
import androidx.compose.foundation.layout.Box import androidx.compose.ui.Modifier import androidx.compose.ui.layout.layout Box( Modifier.layout { measurable, constraints -> if (!constraints.hasBoundedHeight || !constraints.hasBoundedWidth) { // Can't use the ruler. We don't know our size val placeable = measurable.measure(constraints) layout(placeable.width, placeable.height) { placeable.place(0, 0) } } else { // Use the entire space available layout(constraints.maxWidth, constraints.maxHeight) { // Child is measured to fit above the IME val imePosition = SafeBottomRuler.current(-1f) val maxHeight: Int if (imePosition <= 0 || imePosition >= constraints.maxHeight) { // IME ruler is outside the bounds of this layout maxHeight = constraints.maxHeight } else { maxHeight = imePosition.roundToInt() } val minHeight = constraints.minHeight.coerceAtMost(maxHeight) val childConstraints = constraints.copy(minHeight = minHeight, maxHeight = maxHeight) val placeable = measurable.measure(childConstraints) placeable.place(0, 0) } } }, content = content, )
place
fun Placeable.place(position: IntOffset, zIndex: Float = 0.0f): Unit
Place a Placeable at position in its parent's coordinate system. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
place
fun Placeable.place(x: Int, y: Int, zIndex: Float = 0.0f): Unit
Place a Placeable at x, y in its parent's coordinate system. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
placeRelative
fun Placeable.placeRelative(position: IntOffset, zIndex: Float = 0.0f): Unit
Place a Placeable at position in its parent's coordinate system. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
placeRelative
fun Placeable.placeRelative(x: Int, y: Int, zIndex: Float = 0.0f): Unit
Place a Placeable at x, y in its parent's coordinate system. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
placeRelativeWithLayer
fun Placeable.placeRelativeWithLayer(
position: IntOffset,
layer: GraphicsLayer,
zIndex: Float = 0.0f
): Unit
Place a Placeable at position in its parent's coordinate system with an introduced graphic layer. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
layer: GraphicsLayer |
|
zIndex: Float = 0.0f |
controls the drawing order for the |
placeRelativeWithLayer
fun Placeable.placeRelativeWithLayer(
position: IntOffset,
zIndex: Float = 0.0f,
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock
): Unit
Place a Placeable at position in its parent's coordinate system with an introduced graphic layer. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock |
You can configure any layer property available on |
placeRelativeWithLayer
fun Placeable.placeRelativeWithLayer(
x: Int,
y: Int,
layer: GraphicsLayer,
zIndex: Float = 0.0f
): Unit
Place a Placeable at x, y in its parent's coordinate system with an introduced graphic layer. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
layer: GraphicsLayer |
|
zIndex: Float = 0.0f |
controls the drawing order for the |
placeRelativeWithLayer
fun Placeable.placeRelativeWithLayer(
x: Int,
y: Int,
zIndex: Float = 0.0f,
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock
): Unit
Place a Placeable at x, y in its parent's coordinate system with an introduced graphic layer. If the layout direction is right-to-left, the given position will be horizontally mirrored so that the position of the Placeable implicitly reacts to RTL layout direction contexts. If this method is used outside the MeasureScope.layout positioning block, the automatic position mirroring will not happen and the Placeable will be placed at the given position, similar to the place method.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock |
You can configure any layer property available on |
placeWithLayer
fun Placeable.placeWithLayer(
position: IntOffset,
layer: GraphicsLayer,
zIndex: Float = 0.0f
): Unit
Place a Placeable at position in its parent's coordinate system with an introduced graphic layer. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
layer: GraphicsLayer |
|
zIndex: Float = 0.0f |
controls the drawing order for the |
placeWithLayer
fun Placeable.placeWithLayer(
position: IntOffset,
zIndex: Float = 0.0f,
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock
): Unit
Place a Placeable at position in its parent's coordinate system with an introduced graphic layer. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
position: IntOffset |
position in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock |
You can configure any layer property available on |
placeWithLayer
fun Placeable.placeWithLayer(
x: Int,
y: Int,
layer: GraphicsLayer,
zIndex: Float = 0.0f
): Unit
Place a Placeable at x, y in its parent's coordinate system with an introduced graphic layer. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
layer: GraphicsLayer |
|
zIndex: Float = 0.0f |
controls the drawing order for the |
placeWithLayer
fun Placeable.placeWithLayer(
x: Int,
y: Int,
zIndex: Float = 0.0f,
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock
): Unit
Place a Placeable at x, y in its parent's coordinate system with an introduced graphic layer. Unlike placeRelative, the given position will not implicitly react in RTL layout direction contexts.
| Parameters | |
|---|---|
x: Int |
x coordinate in the parent's coordinate system. |
y: Int |
y coordinate in the parent's coordinate system. |
zIndex: Float = 0.0f |
controls the drawing order for the |
layerBlock: GraphicsLayerScope.() -> Unit = DefaultLayerBlock |
You can configure any layer property available on |
withMotionFrameOfReferencePlacement
fun withMotionFrameOfReferencePlacement(block: Placeable.PlacementScope.() -> Unit): Unit
Placement done under block, will have their Placeable placed on the same frame of reference as the current layout.
In LayoutCoordinates, this means that the offset introduced under block may be excluded when calculating positions by passing includeMotionFrameOfReference = false in LayoutCoordinates.localPositionOf.
Excluding the position set by certain layouts can be helpful to trigger lookahead based animation when intended. The typical case are layouts that change frequently due to a provided value, like scroll.
Public properties
coordinates
open val coordinates: LayoutCoordinates?
The LayoutCoordinates of this layout, if known or null if the layout hasn't been placed yet. coordinates will be null when determining alignment lines, preventing alignment lines from depending on absolute coordinates.
When coordinates is null, there will always be a follow-up placement call in which coordinates is not-null.
If you read a position from the coordinates during the placement block the block will be automatically re-executed when the parent layout changes a position. If you don't read it the placement block execution can be skipped as an optimization.
import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.Placeable import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.round // Layout so that the first item consumes to half of the width of the screen, if possible. // The remainder of the layouts are positioned horizontally in the remaining space. @Composable fun FirstItemHalf(modifier: Modifier = Modifier, content: @Composable () -> Unit) { val view = LocalView.current Layout( content = content, modifier = modifier, measurePolicy = { measurables, constraints -> var width = constraints.minWidth var height = constraints.minHeight // If this doesn't have a fixed size, just layout horizontally var placeables: List<Placeable>? = null if (measurables.isNotEmpty()) { if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) { width = constraints.maxWidth height = constraints.maxHeight } else { placeables = measurables.map { it.measure(constraints) } width = placeables.sumOf { it.width } height = placeables.maxOf { it.height } } } layout(width, height) { if (placeables != null) { var x = 0 placeables.forEach { it.placeRelative(x, 0) x += it.width } } else if (measurables.isNotEmpty() && coordinates != null) { val coordinates = coordinates!! val positionInWindow = IntArray(2) view.getLocationOnScreen(positionInWindow) val topLeft = coordinates.localToRoot(Offset.Zero).round() + IntOffset(positionInWindow[0], positionInWindow[1]) val displayWidth = view.resources.displayMetrics.widthPixels val halfWay = displayWidth / 2 val c0 = if (topLeft.x < halfWay) { // The first measurable should fit to half way across Constraints.fixed(halfWay - topLeft.x, height) } else { // The first is already past the half way, so just divide it evenly val measureWidth = width / measurables.size Constraints.fixed(measureWidth, height) } val p0 = measurables[0].measure(c0) p0.place(0, 0) // The rest just fit in the remainder of the space var x = p0.width for (i in 1..measurables.lastIndex) { val measureWidth = (width - x) / (measurables.size - i) val p = measurables[i].measure(Constraints.fixed(measureWidth, height)) p.place(x, 0) x += p.width } } } }, ) }
Protected properties
parentLayoutDirection
protected abstract val parentLayoutDirection: LayoutDirection
Keeps the layout direction of the parent of the placeable that is being places using current PlacementScope. Used to support automatic position mirroring for convenient RTL support in custom layouts.
parentWidth
protected abstract val parentWidth: Int
Keeps the parent layout node's width to make the automatic mirroring of the position in RTL environment. If the value is zero, than the Placeable will be be placed to the original position (position will not be mirrored).
Extension functions
getDisplayCutoutBounds
fun Placeable.PlacementScope.getDisplayCutoutBounds(): List<RectRulers>
Returns a List of RectRulers, one RectRulers for each display cutout. Each RectRulers provides values for the bounds of the display cutout. WindowInsetsRulers.DisplayCutout provides the safe inset values for content avoiding all display cutouts.