Why fillMaxWidth() sometimes does nothing
Compose sizing confuses people because Constraints is a min/max range rather than a value. Each sizing modifier transforms the range in a specific way, and reading them that way makes layout deterministic.
We use Google Analytics to see which pages help people. No ads, no profiles. Privacy Policy
129 posts
Compose sizing confuses people because Constraints is a min/max range rather than a value. Each sizing modifier transforms the range in a specific way, and reading them that way makes layout deterministic.
Modifier order changes rendered output because each element wraps the remainder of the chain. The outside-in reading rule resolves padding, background, clickable ripple bounds and clip behaviour in one go.
Modifier looks like a fluent builder but is an ordered immutable linked list. Knowing its actual shape explains chaining, reuse, the modifier parameter convention, and why some combinations do nothing.
Compose's layout system measures every child exactly once. Understanding that single-pass guarantee explains Column, Row and Box, and why some things you could do in View layouts are deliberately impossible.
Compose has two kinds of state holder: plain classes that live in the composition, and ViewModels that outlive it. Knowing which to reach for is what keeps UiState classes from growing to twenty fields.
Compose's recommended architecture is three layers with one-directional dependencies. The split inside the UI layer — elements and state holders — is the one that decides whether a screen can be tested without a device.
CompositionLocal passes values down the composition without parameters. That invisibility is the feature and the danger: three tests for when it is the right tool, and what to use instead when it isn't.
remember dies on rotation. rememberSaveable survives rotation and process death by writing into the saved instance state Bundle — which has limits, costs, and a custom-type story worth knowing before you need it.
Correct hoisting can still produce an unmaintainable codebase. The four failure modes that show up once a screen grows past a few components, and the fixes for each.
Hoisting to a ViewModel is a different decision from hoisting to a parent composable. The dividing question is lifetime, and getting it wrong in either direction has a specific cost.
State hoisting means moving state to the lowest common ancestor of everything that needs it. The trigger is a second reader — not a rule to apply preemptively.
Compose renders in three phases. Where you read state decides which phase invalidates, and moving a read from composition into layout or draw is the single highest-leverage performance change available.