HomeAndroidSuperior Structure ideas. Episode 4 of MAD Expertise: Compose… | by Simona...

Superior Structure ideas. Episode 4 of MAD Expertise: Compose… | by Simona Stojanovic | Android Builders | Feb, 2023


  • Structure section: considered one of three phases of Compose, through which a mum or dad structure defines the sizing and the positioning of its youngster parts
  • A structure: a broad, summary time period used to rapidly outline any UI factor in Compose
  • A structure node: an summary idea used as a visible illustration of 1 factor within the UI tree, created on account of the Composition section in Compose
  • Structure composable: the composable used because the core element of Compose UI. When referred to as throughout Composition, it creates and provides a structure node within the Compose UI tree; the idea for all increased degree layouts like Column, Row, and so on.
  • structure() perform — the start line of placement, which is the second sub-step of the Structure section and takes care of putting youngsters in a Structure composable, proper after the primary sub-step of measurement
  • .structure() modifier — a modifier that wraps one single structure node and permits sizing and putting it individually, as an alternative of this being achieved by its mum or dad structure
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
modifier: Modifier = Modifier
) {
Structure() { … }
}
@Composable inline enjoyable Structure(
content material: @Composable @UiComposable () -> Unit,
modifier: Modifier = Modifier,
measurePolicy: MeasurePolicy
) {
// …
}
  • Structure — for measuring and putting 0 or extra youngsters, which accepts one composable as content material
  • Structure — for leaf nodes of the UI tree with exactly 0 youngsters, so it doesn’t have a content material parameter
  • Structure — accepts a contents listing for passing a number of totally different composables
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
modifier: Modifier = Modifier
) {
Structure(
content material = content material,
modifier = modifier,
measurePolicy = { measurables, constraints ->
// 1. Measurement step
// Decide sizes of elements
structure(…) {
// 2. Placement step
// Decide positions of elements
}
}
)
}
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
modifier: Modifier = Modifier
) {
Structure(
content material = content material,
modifier = modifier,
measurePolicy = { measurables, constraints ->
// MEASUREMENT SCOPE
// 1. Measurement step
// Decide sizes of elements
structure(…) {
// PLACEMENT SCOPE
// 2. Placement step
// Decide positions of elements
}
}
)
}
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
// …
) {
Structure(
content material = content material,
modifier = modifier
measurePolicy = { measurables: Checklist<Measurable>, constraints: Constraints ->
// MEASUREMENT SCOPE
// 1. Measurement step
// Decide sizes of elements
}
)
}
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
// …
) {
Structure(
content material = content material,
modifier = modifier
) { measurables, constraints ->
// MEASUREMENT SCOPE
// 1. Measurement step
measurables.map { measurable ->
measurable.measure(constraints)
}
}
}
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
// …
) {
Structure(
content material = content material,
modifier = modifier
) { measurables, constraints ->
// MEASUREMENT SCOPE
// 1. Measurement step
measurables.map { measurable ->
measurable.measure(
constraints.copy(
minWidth = newWidth,
maxWidth = newWidth
)
)
}
}
}
@Composable
enjoyable CustomLayout(
content material: @Composable () -> Unit,
// …
) {
Structure(
content material = content material,
modifier = modifier
) { measurables, constraints ->
// MEASUREMENT SCOPE
// 1. Measurement step
val placeables = measurables.map { measurable ->
// Returns a placeable
measurable.measure(constraints)
}
}
}
@Composable
enjoyable CustomLayout(
// …
) {
Structure(
// …
) {
// totalWidth could possibly be the sum of all youngsters's widths
// totalHeight could possibly be the sum of all youngsters's heights
structure(totalWidth, totalHeight) {
// PLACEMENT SCOPE
// 2. Placement step
}
}
}
@Composable
enjoyable CustomLayout(
// …
) {
Structure(
// …
) {
// …
structure(totalWidth, totalHeight) {
// PLACEMENT SCOPE
// 2. Placement step
placeables // PLACE US! 😎
}
}
}
@Composable
enjoyable CustomLayout(
// …
) {
Structure(
// …
) {
// …
structure(totalWidth, totalHeight) {
// PLACEMENT SCOPE
// 2. Placement step
placeables.map { it.place(xPosition, yPosition) }
}
}
}
@Composable
enjoyable LayoutModifierExample() {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Coloration.LightGray)
.padding(40.dp)
) {
Aspect()
Aspect()
// Merchandise under ought to insurgent towards the enforced padding and go edge to edge
Aspect()
Aspect()
}
}
Modifier.structure { measurable, constraints ->
// Measurement
val placeable = measurable.measure(...)

structure(placeable.width, placeable.top) {
// Placement
placeable.place(...)
}
}

Aspect(modifier = Modifier.structure { measurable, constraints ->
val placeable = measurable.measure(
constraints.copy(
// Resize this merchandise's maxWidth by including DPs to incoming constraints
maxWidth = constraints.maxWidth + 80.dp.roundToPx()
)
)
structure(placeable.width, placeable.top) {
// Place this merchandise within the authentic place
placeable.place(0, 0)
}
})
BoxWithConstraints {
// maxHeight is the measurement data accessible solely in BoxWithConstraints,
// as a result of deferred Composition section occurring AFTER Structure section measurement
if (maxHeight < 300.dp) {
SmallImage()
} else {
BigImage()
}
}

SubcompositionLayout DON’Ts

Traversing a tree with plenty of UI nodes for every recomposition
@Composable
enjoyable IntrinsicExample() {
Column() {
Textual content(textual content = "MAD")
Textual content(textual content = "Expertise")
Textual content(textual content = "Layouts")
Textual content(textual content = "And Modifiers")
}
}
@Composable
enjoyable IntrinsicExample() {
Column() {
Textual content(textual content = "MAD", Modifier.fillMaxWidth())
Textual content(textual content = "Expertise", Modifier.fillMaxWidth())
Textual content(textual content = "Layouts", Modifier.fillMaxWidth())
Textual content(textual content = "And Modifiers", Modifier.fillMaxWidth())
}
}
@Composable
enjoyable IntrinsicExample() {
Column(Modifier.width(IntrinsicSize.Max)) {
Textual content(textual content = "MAD", Modifier.fillMaxWidth())
Textual content(textual content = "Expertise", Modifier.fillMaxWidth())
Textual content(textual content = "Layouts", Modifier.fillMaxWidth())
Textual content(textual content = "And Modifiers", Modifier.fillMaxWidth())
}
}
@Composable
enjoyable IntrinsicExample() {
Column(Modifier.width(IntrinsicSize.Min) {
Textual content(textual content = "MAD", Modifier.fillMaxWidth())
Textual content(textual content = "Expertise", Modifier.fillMaxWidth())
Textual content(textual content = "Layouts", Modifier.fillMaxWidth())
Textual content(textual content = "And Modifiers", Modifier.fillMaxWidth())
}
}
  • Modifier.width(IntrinsicSize.Min) — “What’s the minimal width it’s worthwhile to show your content material correctly?”
  • Modifier.width(IntrinsicSize.Max) — “What’s the utmost width it’s worthwhile to show your content material correctly?”
  • Modifier.top(IntrinsicSize.Min) — “What’s the minimal top it’s worthwhile to show your content material correctly?”
  • Modifier.top(IntrinsicSize.Max) — “What’s the utmost top it’s worthwhile to show your content material correctly?”
    Structure(
modifier = modifier,
content material = content material,
measurePolicy = object : MeasurePolicy {
override enjoyable MeasureScope.measure(
measurables: Checklist<Measurable>,
constraints: Constraints
): MeasureResult {
// Measure and structure right here
}

override enjoyable IntrinsicMeasureScope.maxIntrinsicHeight(
measurables: Checklist<IntrinsicMeasurable>,
width: Int
): Int {
// Logic for calculating customized maxIntrinsicHeight right here
}

// Different intrinsics associated strategies have a default worth,
// you'll be able to override solely the strategies that you just want.
}
)

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments