Compose Layout, Lists & Modifiers Quiz

UI › Compose UI

You write Box(Modifier.size(100.dp).background(Color.Blue).padding(20.dp)) wrapping a Text. What does the blue region look like?

Answer: The whole 100.dp box is blue, and the Text is inset by 20.dp

background is applied before padding here, so the whole 100.dp area is painted blue and the padding then insets the Text within that blue region.

In a horizontally heterogeneous LazyColumn (headers and rows), what does adding contentType to items() primarily improve?

Answer: It lets Compose reuse compositions only within the same type

contentType scopes composition reuse to matching types so a scrolled-off header isn't reused as a row, making recycling in mixed lists more efficient.

Which statement about Modifier.weight(1f) is correct?

Answer: It only compiles as a direct child of a Row or Column

weight is defined on RowScope and ColumnScope, so it's scope-restricted to direct children of a Row or Column and proportionally divides the remaining space.

A list scrolls back to the top and loses each row's expanded/collapsed state after the data list is reordered. What is the most likely cause?

Answer: The items had no stable key, so Compose couldn't track identity

Without stable keys, Compose falls back to positional identity, so reordering reassigns remembered state to the wrong items and resets it. Stable keys preserve per-item state across data changes.

What is the difference between Modifier.size(100.dp) and Modifier.requiredSize(100.dp)?

Answer: size obeys parent constraints; requiredSize forces the 100.dp anyway

size proposes a measurement that the parent's constraints can still clamp, whereas requiredSize ignores those constraints and forces the exact dimension, potentially overflowing the parent.

Why does putting a LazyColumn directly inside a Column(Modifier.verticalScroll(...)) throw at runtime?

Answer: The scrolling parent offers infinite height, so the list can't measure

A vertically scrolling Column offers unbounded height, leaving the LazyColumn with no finite viewport to size against, which throws an IllegalStateException. Flatten to one LazyColumn or bound the inner height.

You want to pass the current theme's spacing to many nested composables without adding parameters to each. Which tool fits best?

Answer: A CompositionLocal used with CompositionLocalProvider

CompositionLocal provides a value implicitly down the composition tree via CompositionLocalProvider, letting descendants read it with .current without prop-drilling through every layer.

A Box uses contentAlignment = Alignment.Center for most children, but one badge child must sit in the top-end corner instead. How do you override alignment for just that child?

Answer: Apply Modifier.align(Alignment.TopEnd) to that child

BoxScope exposes Modifier.align, which lets an individual child override the Box's contentAlignment, so the badge can be placed at TopEnd while siblings stay centered.

When the value supplied to a staticCompositionLocalOf changes at the provider, what recomposes?

Answer: The whole CompositionLocalProvider subtree, even if it never reads it

staticCompositionLocalOf does not track individual reads, so any change forces the whole provided subtree to recompose; compositionLocalOf instead tracks reads and recomposes only the readers.

Inside a Box whose size is determined by its largest child, you add a background layer that should exactly match the Box's final measured size without affecting how that size is computed. Which modifier fits?

Answer: Modifier.matchParentSize()

BoxScope.matchParentSize sizes the child to the Box's resolved size but is excluded when the Box measures itself, so it never grows the Box; fillMaxSize fills incoming max constraints and does participate in sizing.

Your LazyColumn rows use Modifier.animateItem(), but nothing animates when the underlying list is reordered. What is the most likely fix?

Answer: Provide a stable key in items() so Compose tracks identity

animateItem only animates moves, insertions, and removals when items have stable keys; without keys Compose uses positional identity and cannot tell that an item moved.

On a Text, how does Modifier.clickable{}.padding(16.dp) differ from Modifier.padding(16.dp).clickable{}?

Answer: clickable-first ripples over the padding; padding-first clicks only the content

Modifiers apply outside-in, so a clickable placed before padding extends the touch target and ripple across the padded region, while padding placed first shrinks the clickable area down to the content.

You want a uniform 8.dp gap between every child of a Column, with no extra space above the first child or below the last. What is the cleanest approach?

Answer: Column(verticalArrangement = Arrangement.spacedBy(8.dp))

Arrangement.spacedBy inserts the gap only between adjacent children and not at the outer edges; per-child vertical padding would also add space at the top and bottom and double up between items, and Column has no contentPadding parameter.

In a Row containing two Texts, you want a vertical Divider between them to be exactly as tall as the taller Text. Which approach works in Compose's single-pass layout?

Answer: Give the Row height(IntrinsicSize.Min), then fillMaxHeight the divider

IntrinsicSize.Min makes the Row pre-query its children's intrinsic heights so the Row's height resolves to the taller Text, letting the divider's fillMaxHeight fill that height; fillMaxHeight by itself has no fixed height to fill in an otherwise wrap-height Row.

Back to Compose Layout, Lists & Modifiers