Master Adaptive Design in Jetpack Compose (2025)

Adaptive Design

Design once, run anywhere - phone, tablet, foldable, or desktop. Learn Window Size Classes, BoxWithConstraints, Adaptive Scaffold, and more to scale beautifully across screens.

What you’ll learn

  • What is Adaptive Design?
  • Window Size Classes (Material 3)
  • BoxWithConstraints for responsive swaps
  • Navigation Rail vs Bottom Bar
  • Lazy Grids & Lists
  • TwoPane / SlidingPaneLayout
  • Insets & Safe Areas
  • Orientation & Posture handling
  • Adaptive Scaffold
  • Responsive Typography & Spacing
  • Multi-device Previews

What is Adaptive Design?

Design once, adapt everywhere - phone, tablet, foldable, desktop.

When to use: Build scalable UIs that adjust layout and navigation by available width.

@Composable
fun AdaptiveApp() {
    when (WindowWidthSizeClass.calculate()) {
        Compact  -> PhoneUI()
        Medium   -> TabletUI()
        Expanded -> DesktopUI()
    }
}

Window Size Classes

Material 3’s official breakpoints for adaptive UI.

When to use: Decide single- vs two-pane layouts based on width class.

val window = calculateWindowSizeClass(activity)
if (window.widthSizeClass >= Medium) TwoPaneLayout() else SinglePaneLayout()

BoxWithConstraints

React to available space dynamically.

When to use: Swap content without global window info.

BoxWithConstraints {
    if (maxWidth > 600.dp) WideCard() else CompactCard()
}

Navigation Rail vs Bottom Bar

Switch navigation type by width.

When to use: Phones → Bottom Bar, Tablets/Desktop → Navigation Rail.

if (window.widthSizeClass >= Medium) NavigationRail() else NavigationBar()

Lazy Grids & Lists

Fit columns automatically with GridCells.Adaptive.

When to use: Galleries, product grids, dashboards.

LazyVerticalGrid(columns = GridCells.Adaptive(140.dp)) {
    items(50) { CardItem(it) }
}

SlidingPaneLayout / TwoPane

Show list and detail side-by-side.

When to use: Master–detail on tablets and foldables.

TwoPane(
  first = { ListPane() },
  second = { DetailPane() },
  strategy = HorizontalTwoPaneStrategy()
)

Insets & Safe Areas

Respect system bars, notches, and gestures.

When to use: Edge-to-edge or immersive layouts.

Column(
  Modifier.statusBarsPadding()
          .navigationBarsPadding()
) {
  Content()
}

Orientation & Posture

Detect fold posture and rotation.

When to use: Optimize dual-screen and landscape UIs.

val posture = windowInfoRepo.windowLayoutInfo.collectAsState()
if (posture.value.displayFeatures.isNotEmpty()) DualPane() else SinglePane()

Adaptive Scaffold

Manage bars, FABs, and inner paddings responsively.

When to use: Base shell for multi-device screens.

Scaffold(
  topBar = { TopAppBar(title = { Text("Home") }) },
  bottomBar = { if (isCompact) BottomBar() }
) { inner ->
  Content(Modifier.padding(inner))
}

Responsive Typography & Spacing

Scale type and padding for readability.

When to use: Larger screens and TV-like distances.

val isLarge = window.widthSizeClass >= Expanded
Text("Hello", fontSize = if (isLarge) 24.sp else 16.sp)

Preview for Devices

Validate layouts on multiple virtual screens.

When to use: Catch adaptive issues before release.

@Preview(device = Devices.TABLET)
@Composable fun PreviewTablet() { AdaptiveApp() }

Final Tips

  • Use WindowSizeClass for layout decisions
  • Prefer Adaptive Scaffold + Insets
  • Test on phones, tablets, foldables
  • Avoid hardcoded sizes; keep modifiers flexible
  • Preview with multiple configurations

Thank You - Follow Boltuix

Daily Jetpack Compose insights - layouts, adaptive UI, production tips.


#Android #JetpackCompose #MaterialDesign #AdaptiveUI #Kotlin #AndroidDevelopers


Post a Comment

Previous Post Next Post