Skip to main content
Blog
android

Jetpack Compose Adaptive Layouts in 2026: A Practical Guide to Grid, Flexbox, and MediaQuery

Jetpack Compose 1.11 ships Grid, Flexbox, and MediaQuery for adaptive UI. Here's how indie devs build one app that works on phones, foldables, and TVs.

Carlton Aikins7 min read

For years, "support tablets" was a line item indie Android developers quietly skipped. The phone build worked, the tablet got a stretched version of the phone build, and nobody complained loudly enough to make it worth a rewrite. That era is ending. With Android 17's "Adaptive Everywhere" push and Jetpack Compose 1.11's new layout primitives, building one UI that genuinely adapts across phones, foldables, tablets, desktop windows, and TVs is now a realistic goal for a one-person team — and increasingly, an expectation rather than a nice-to-have.

This guide walks through what actually changed in Compose 1.11, what each new primitive is for, and a migration path that fits a small team's time budget. It also covers the part most adaptive-layout guides skip: shipping to more form factors multiplies your store presence, not just your codebase.

Why adaptive layouts stopped being optional#

The shift here is strategic, not just technical. Android 17 completes a years-long move toward a single platform that spans phones, cars, living rooms, foldables, desktop windowing, and XR. Google has steadily made large-screen quality a discovery and ranking signal on Google Play — apps that break or letterbox on a tablet get filtered down in the surfaces where large-screen users actually browse.

For a big team, the old answer was to maintain separate layouts per form factor. For an indie or a small team, that math never worked: every new form factor was another layout tree to keep in sync, another source of bugs. Compose 1.11's adaptive primitives are an attempt to make "one layout, many shapes" the default path instead of the heroic one.

What's actually new in Compose 1.11#

Compose 1.11 introduces a set of building blocks aimed squarely at responsive layout. The four that matter most:

Grid — a true two-dimensional layout API for arranging content in rows and columns without nesting Rows inside Columns, and without reaching for a lazy grid when your content isn't actually lazy.

Flexbox — a layout that lets children grow, shrink, and wrap based on available space, borrowed conceptually from the web's flexbox model.

MediaQuery — a way to make composables respond to the characteristics of the available window (size, aspect, and similar) rather than to a hardcoded notion of "phone" or "tablet."

Style — a mechanism for bundling and reusing visual styling decisions so adaptive variants don't turn into a pile of copy-pasted modifiers.

Taken together, these move Compose closer to how responsive web layout has worked for a decade: you describe constraints and let the layout resolve itself, instead of branching on device type.

The Grid API#

Grid is the one most teams will reach for first. Before 1.11, building a dense two-dimensional screen — a dashboard, a settings page with paired controls, a media gallery with a structured layout — meant either nesting rows and columns by hand (brittle, hard to align) or pulling in LazyVerticalGrid even when every item was on screen at once (overhead you don't need, and awkward to compose with non-grid content).

Grid gives you the structural control of a real grid system: define your columns or tracks, place items, let the layout handle alignment and sizing. The key distinction from the lazy grids: use Grid for screen-level architecture and complex, fully-materialized components; keep LazyVerticalGrid for genuinely long, scrolling collections. Mixing them up is the most common early mistake — a lazy grid for a six-item dashboard is wasted machinery.

Flexbox and MediaQuery: stop branching on "is tablet"#

Flexbox handles the case where you have a set of children that should distribute themselves across the available space — growing to fill it, shrinking to fit, and wrapping to a new line when they run out of room. A toolbar of actions, a row of filter chips, a set of cards: all of these are flexbox problems, and all of them previously involved manual width math or FlowRow workarounds.

MediaQuery is the bigger mental shift. The instinct most Android developers built up over a decade is to branch on device type: if tablet, show two panes; else show one. That logic breaks the moment a foldable is half-open, a phone app is running in a freeform desktop window, or a tablet is split-screened down to phone width. The device hasn't changed, but the space the app has to work with has.

MediaQuery lets you respond to the actual window the app is rendering into. The rule of thumb: branch on available width, never on device identity. A 600dp-wide window gets the two-pane layout whether that window is a tablet, an unfolded foldable, or a phone app docked next to another on a desktop. This is also why window size classes — compact, medium, expanded — are worth adopting as the backbone of your adaptive logic. They give you a small, stable set of breakpoints instead of a sprawl of pixel checks.

A migration path that fits a one-person team#

You don't have to rewrite your app. A realistic, incremental path:

1. Adopt window size classes as your top-level signal. Thread a size class down from your root composable. Even before you change a single screen, this gives you the vocabulary to make adaptive decisions consistently.

2. Find your single worst screen. Run your app in a resizable emulator and unfold it, or split-screen it on a real device. One screen will be visibly broken — letterboxed, stretched, or with controls stranded. That's your first target. Don't try to do the whole app at once.

3. Replace device checks with MediaQuery or size-class branches. Search your codebase for anything that reads screen dimensions or smallestScreenWidthDp to decide layout. Each one is a latent bug on foldables and desktop windows. Convert them to width-based decisions.

4. Use Grid for the dense screens, Flexbox for the flowing ones. Rebuild the worst screen with the right primitive instead of nested rows and columns. You'll usually delete code in the process.

5. Test where it actually breaks. The resizable emulator, foldable configurations, split-screen, and desktop windowing are where adaptive bugs live. A screen that looks fine at phone width and tablet width can still break at every width in between — drag the window slowly and watch.

The form factor you forgot: your store listing#

Here's the part that doesn't show up in layout tutorials. Every form factor you now genuinely support is also a store surface. Google Play wants large-screen screenshots to rank your app well in tablet and foldable discovery. The App Store, if you're shipping cross-platform, has its own per-device screenshot requirements. A tablet build with no tablet screenshots is, from a discovery standpoint, an app that doesn't support tablets — the work you did in code is invisible where users actually decide.

So the adaptive-layout project has a tail: once your Compose UI looks right on a foldable and a tablet and a desktop window, you now owe the stores a screenshot set for each of those, kept current as the UI changes. For a small team, that tail is often longer than the layout work itself, and it's the part that quietly rots — the code adapts, the screenshots don't.

This is where tooling earns its place. Stora generates per-device screenshot sets and store listings from your actual build, so when you add real foldable and tablet support, the App Store and Play Store listings reflect it without a manual capture-and-crop session per device. Its compliance engine also catches the mismatch case — a listing that still claims phone-only while the binary now handles large screens, or vice versa. The point isn't to skip the layout work; it's to make sure the layout work actually shows up where it converts.

Wrapping up#

Compose 1.11's adaptive primitives — Grid, Flexbox, MediaQuery, and Style — finally make "one app, every form factor" a default rather than a heroic effort. The technical path is incremental: adopt window size classes, fix your worst screen, replace device checks with width-based logic, and test by resizing rather than by guessing. Just remember that the project doesn't end at the code. Every form factor you support is also a store listing and a screenshot set, and an adaptive app with a phone-only listing is only half-shipped. Build the layout, then make sure the storefront tells the same story.