Contents — page 2 of 4
Day 26FlowRow is the chip group you kept writing a custom Layout forFlowRow and FlowColumn wrap children onto new lines when they run out of room. They replace the custom Layout most codebases wrote for chip groups, and the overflow API handles the 'and 4 more' case.Day 27Sometimes the right grid is a Column of RowsNot every grid needs LazyVerticalGrid. For a small fixed set — a keypad, a colour picker, a dashboard — a Column of Rows is simpler, cheaper and easier to reason about. Knowing the cutoff matters.Day 28Porting FlexboxLayout: every flex property maps onto something, but not onto one thingThere is no FlexboxLayout in Compose because flex's properties split cleanly across Row/Column, Arrangement, Alignment and FlowRow. A direct property-by-property mapping for anyone porting a View layout.Day 29Screen size is the wrong thing to branch on. Window size is the right one.Window size classes replace device-type checks with a measure of the window your app actually occupies. Three buckets per axis, recomputed live, and the reason isTablet() has been wrong for years.Day 30There are three adaptive layouts, and you probably don't need a fourthMaterial's canonical layouts give three tested patterns for adapting across window sizes. Knowing which one a screen is saves designing an adaptive layout from scratch, and the library implements two of them directly.Day 31ListDetailPaneScaffold: the back button is the whole reason it existsListDetailPaneScaffold adapts a list and detail across window sizes, but its real value is the navigator — which makes back pop the detail on compact and exit the screen on expanded, from one implementation.Day 32SupportingPaneScaffold is for content that is about other contentSupportingPaneScaffold docks secondary content beside a primary view on wide windows and collapses it to a sheet on narrow ones. Choosing it over list-detail is a question about what the second pane contains.Day 33A hinge is a physical object, and your layout should know where it isFoldables give two things a resize doesn't: a posture and a hinge with real coordinates. Handling them well means avoiding the seam and using tabletop mode, not just supporting a new width.Day 34An external display is a second window, not a bigger oneAndroid 16 makes external displays a mainstream concern. The layout work is mostly window size classes you already have; the new parts are density, input capability and deciding what belongs on which screen.Day 35The Scaffold parameter everyone ignores is the one that breaks the layoutScaffold arranges the app shell and hands back the insets its own bars consume. Ignoring that PaddingValues is the single most common Compose layout bug, and edge-to-edge makes it worse.Day 36Five buttons, one hierarchy, and the rule that decides whichMaterial 3 ships five button styles plus the FAB. They form an emphasis hierarchy, and the selection rule is about how many actions compete on a screen rather than about how each one looks.Day 37Checkbox, radio, switch: three controls, three different questionsCheckboxes, radio buttons and switches encode different semantics — multiple choice, exclusive choice, and immediate effect. Choosing by appearance produces interfaces that mislead, and the accessibility story differs too.Day 38The TextField overload you're using is probably the deprecated oneCompose has two TextField APIs. The String + onValueChange pair has real problems with cursor position and asynchronous updates; the TextFieldState overload solves them and is now the recommended one.Day 39A dialog is state, not a function you callDialogs and bottom sheets are composables that exist conditionally, not imperative calls. Modelling them as state fixes the rotation bug, the double-show bug, and the question of where the result goes.Day 40Bar, rail, drawer — the same destinations, chosen by window widthNavigationBar, NavigationRail and the drawer are three presentations of the same destination list. Window size decides which, and NavigationSuiteScaffold does the switching — with rules about how many destinations belong there at all.Day 41The spinner you show for 200ms is worse than no spinnerCompose gives you progress indicators; it doesn't tell you when to show one. Duration decides: under 300ms show nothing, over a second show progress, and never let an indicator replace content that could be a skeleton.Day 42Date pickers are a timezone bug with a calendar attachedCompose's date and time pickers are straightforward components hiding a genuine trap: the selected value is UTC-midnight epoch millis, and converting it naively shifts dates by one in most of the world.Day 43SearchBar has two states, and the second one takes over the screenMaterial 3's SearchBar transitions into a full-screen suggestion surface, which makes it a navigation concern. Chips come in four semantic variants, and the assist/filter/input/suggestion split matters.Day 44MaterialTheme is three CompositionLocals and nothing elseMaterialTheme provides three CompositionLocals and a handful of defaults. Understanding its actual shape explains how components pick up styling, why hardcoded values break dark mode, and what a custom theme has to replace.Day 45Dynamic colour takes your brand palette away, and that's the dealDynamic colour derives a full Material scheme from the user's wallpaper. It improves the feel of most apps and destroys brand recognition if applied indiscriminately, so the interesting work is deciding what stays fixed.Day 46Fifteen named text styles are fewer decisions than fiveMaterial's type scale gives fifteen named roles instead of a font-size parameter. Naming the role rather than the size is what makes typography consistent across a team and correct at large font scales.Day 47Corner radius is a signal, and Material has five of themMaterial's shape scale gives five corner sizes mapped to component categories. The system is simple; the interesting parts are clip ordering, asymmetric corners, and shapes that must respond to state.Day 48Extending MaterialTheme beats replacing it, until it doesn'tMaterial models colour, type and shape. Everything else a design system needs — spacing, motion, semantic colour — has to be added. Extending with a parallel CompositionLocal is usually right; a full custom system rarely is.Day 49Compose is growing a styles API, and it's for the gap theming never coveredMaterialTheme scopes values to a subtree, which is the wrong shape for reusable per-component configuration. Compose's styles direction addresses that gap; wrapper composables are the pattern to use today.Day 50AnnotatedString is why you don't need three Text composables in a RowText takes a String or an AnnotatedString. The second lets one composable carry multiple styles, inline content and clickable spans — replacing the Row of Texts that breaks at large font scales.