In Jetpack Compose every size Modifier passes a class called Constraints
which contains minWidth, maxWidth, minHeight, maxHeight params. You can refer Constraints section of answer below to see which size Modifier returns which Constraints.
https://stackoverflow.com/a/73316247/5457853
Modifier.width creates a fixed min-max SizeNode for instance.
These are done inside measure function of MeasurePolicy.
@Composable
private fun MyLayout(
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val measurePolicy = object : MeasurePolicy {
override fun MeasureScope.measure(
measurables: List<Measurable>,
constraints: Constraints
): MeasureResult {
// Measure Measurables(content Composables)
val placeables = measurables.map { measurable ->
measurable.measure(constraints)
}
// Calculate based on your logic
val layoutWidth = ...
val layoutHeight= ...
// Set Layout dimensions
return layout(layoutWidth, layoutHeight) {
// Place them vertically, horizontall, or based on custom logic
placeables.foreaach{it.placeRelative)
}
}
}
Layout(
modifier = modifier,
content = content,
measurePolicy = measurePolicy
)
}
Then using these Constraints;
After Composition phase, during the Layout phase, the tree is traversed using the following 3 step algorithm:
1-) Measure children: A node measures its children, if any.
2-) Decide own size: Based on those measurements, a node decides on
its own size.
3-) Place children: Each child node is placed relative to a node’s own
position.
// 1-) We measure contents of a layout via Measurables(Composable inside layout) using Constraints(ranges that come from size or scroll Modifiers or parent Constraints)
val placeables = measurables.map { measurable ->
measurable.measure(constraints)
}
After getting Placeables we need to decide what kind of Composables we want to build. This is a Column in this example, based on your logic you measure layout width and height differently and place Placeables accordingly. Calculate dimensions of this Layout
first(dimensions of Layout).
Simplified logic for Column is to get total height of Placeables and max of Placeable if there is no size modifier, if there is any that is not infinite use it.
// 2-) After measuring each child we decide how big this Layout/Composable should be
// Let's say we want to make a Column we need to set width to max of content Composables
// while sum of content Composables
val layoutWidth = placeables.maxOf { it.width }
val layoutHeight = placeables.sumOf { it.height }
In third step we set layout dimensions and place these Composables. Since i build a Column, i place each Placeable after another vertically.
layout(layoutWidth, layoutHeight) {
// 3-) Place placeables or Composables
// In this example we place like a Column vertically
var y = 0
placeables.forEach { placeable: Placeable ->
placeable.placeRelative(0, y)
y += placeable.height
}
}
You can find several examples about Layout, Constraints, Size Modifiers, Constraints bounds, infinite Constraints and more in this tutorial.
https://github.com/SmartToolFactory/Jetpack-Compose-Tutorials/tree/master/Tutorial1-1Basics/src/main/java/com/smarttoolfactory/tutorial1_1basics