LayoutModifierNode
-
Cmn
interface LayoutModifierNode : DelegatableNode
ApproachLayoutModifierNode |
|
A Modifier.Node that changes how its wrapped content is measured and laid out. It has the same measurement and layout functionality as the androidx.compose.ui.layout.Layout component, while wrapping exactly one layout due to it being a modifier. In contrast, the androidx.compose.ui.layout.Layout component is used to define the layout behavior of multiple children.
This is the androidx.compose.ui.Modifier.Node equivalent of androidx.compose.ui.layout.LayoutModifier
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.LayoutModifier import androidx.compose.ui.layout.Measurable import androidx.compose.ui.layout.MeasureResult import androidx.compose.ui.layout.MeasureScope import androidx.compose.ui.layout.layout import androidx.compose.ui.node.LayoutModifierNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.platform.InspectorInfo import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.offset class VerticalPadding(var padding: Dp) : LayoutModifierNode, Modifier.Node() { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints, ): MeasureResult { val paddingPx = padding.roundToPx() val placeable = measurable.measure(constraints.offset(vertical = -paddingPx)) return layout(placeable.width, placeable.height + paddingPx) { placeable.placeRelative(0, paddingPx) } } } data class VerticalPaddingElement(val padding: Dp) : ModifierNodeElement<VerticalPadding>() { override fun create() = VerticalPadding(padding) override fun update(node: VerticalPadding) { node.padding = padding } override fun InspectorInfo.inspectableProperties() { name = "verticalPadding" properties["padding"] = padding } } fun Modifier.verticalPadding(padding: Dp) = this then VerticalPaddingElement(padding) Box(Modifier.background(Color.Gray).verticalPadding(50.dp)) { Box(Modifier.fillMaxSize().background(Color.DarkGray)) }
| See also | |
|---|---|
Layout |
Summary
Public functions |
||
|---|---|---|
open Int |
IntrinsicMeasureScope.maxIntrinsicHeight(The lambda used to calculate |
Cmn
|
open Int |
IntrinsicMeasureScope.maxIntrinsicWidth(The function used to calculate |
Cmn
|
MeasureResult |
MeasureScope.measure(measurable: Measurable, constraints: Constraints)The function used to measure the modifier. |
Cmn
|
open Int |
IntrinsicMeasureScope.minIntrinsicHeight(The lambda used to calculate |
Cmn
|
open Int |
IntrinsicMeasureScope.minIntrinsicWidth(The function used to calculate |
Cmn
|
Extension functions |
||
|---|---|---|
Unit |
This will invalidate the current node's layer, and ensure that the layer is redrawn for the next frame. |
Cmn
|
Unit |
This invalidates the current node's measure result, and ensures that a re-measurement (the measurement block rerun) of this node will happen for the next frame. |
Cmn
|
Unit |
This will invalidate the current node's placement result, and ensure that relayout (the placement block rerun) of this node will happen for the next frame . |
Cmn
|
Unit |
Performs the node remeasuring synchronously even if the node was not marked as needs remeasure before. |
Cmn
|
Unit |
LayoutModifierNode.updateLayerBlock(layerBlock: (GraphicsLayerScope.() -> Unit)?)Updates the layer block of the |
Cmn
|
Inherited functions |
|---|
Inherited properties |
|||
|---|---|---|---|
|
Public functions
maxIntrinsicHeight
open fun IntrinsicMeasureScope.maxIntrinsicHeight(
measurable: IntrinsicMeasurable,
width: Int
): Int
The lambda used to calculate IntrinsicMeasurable.maxIntrinsicHeight.
maxIntrinsicWidth
open fun IntrinsicMeasureScope.maxIntrinsicWidth(
measurable: IntrinsicMeasurable,
height: Int
): Int
The function used to calculate IntrinsicMeasurable.maxIntrinsicWidth.
measure
fun MeasureScope.measure(measurable: Measurable, constraints: Constraints): MeasureResult
The function used to measure the modifier. The measurable corresponds to the wrapped content, and it can be measured with the desired constraints according to the logic of the LayoutModifierNode. The modifier needs to choose its own size, which can depend on the size chosen by the wrapped content (the obtained Placeable), if the wrapped content was measured. The size needs to be returned as part of a MeasureResult, alongside the placement logic of the Placeable, which defines how the wrapped content should be positioned inside the LayoutModifierNode. A convenient way to create the MeasureResult is to use the MeasureScope.layout factory function.
A LayoutModifierNode uses the same measurement and layout concepts and principles as a androidx.compose.ui.layout.Layout, the only difference is that they apply to exactly one child. For a more detailed explanation of measurement and layout, see androidx.compose.ui.layout.MeasurePolicy.
minIntrinsicHeight
open fun IntrinsicMeasureScope.minIntrinsicHeight(
measurable: IntrinsicMeasurable,
width: Int
): Int
The lambda used to calculate IntrinsicMeasurable.minIntrinsicHeight.
minIntrinsicWidth
open fun IntrinsicMeasureScope.minIntrinsicWidth(
measurable: IntrinsicMeasurable,
height: Int
): Int
The function used to calculate IntrinsicMeasurable.minIntrinsicWidth.
Extension functions
invalidateLayer
fun LayoutModifierNode.invalidateLayer(): Unit
This will invalidate the current node's layer, and ensure that the layer is redrawn for the next frame.
invalidateMeasurement
fun LayoutModifierNode.invalidateMeasurement(): Unit
This invalidates the current node's measure result, and ensures that a re-measurement (the measurement block rerun) of this node will happen for the next frame.
invalidatePlacement
fun LayoutModifierNode.invalidatePlacement(): Unit
This will invalidate the current node's placement result, and ensure that relayout (the placement block rerun) of this node will happen for the next frame .
remeasureSync
fun LayoutModifierNode.remeasureSync(): Unit
Performs the node remeasuring synchronously even if the node was not marked as needs remeasure before. Useful for cases like when during scrolling you need to re-execute the measure block to consume the scroll offset and remeasure your children in a blocking way.
updateLayerBlock
fun LayoutModifierNode.updateLayerBlock(layerBlock: (GraphicsLayerScope.() -> Unit)?): Unit
Updates the layer block of the LayoutModifierNode. This will mark the layer as invalidated and schedule a refresh of the layer.
Updating the layer lambda using this method is cheaper than invalidating placement and placing the layout with a new layer block. This API is expected to be used alongside Placeable.placeAt with a layerBlock parameter passed. This will override/update the layerBlock passed in that API. Whichever one was called last should "win".
| Parameters | |
|---|---|
layerBlock: (GraphicsLayerScope.() -> Unit)? |
the snapshot-observed lambda used to set properties on the layer. if |
| See also | |
|---|---|
placeAt |