DEV Community

Cover image for About Window size class libraries
Thomas Künneth
Thomas Künneth

Posted on

About Window size class libraries

With the first stable version of Material Design 3 for Compose, which was released last October, we also got a new small library called androidx.compose.material3:material3-window-size-class. It deals with Window size classes.

Window size classes group widths and heights into three groups, Compact, Medium, and Expanded.

Group horizontal vertical
Compact < 600 dp < 480 dp
Medium < 840 dp < 900 dp
Expanded ≥ 840 dp ≥ 900 dp

The idea is to use this broad classification to define your screen layout. To achieve this, package androidx.compose.material3.windowsizeclass provides a top-level composable function named calculateWindowSizeClass(activity: Activity) which returns an instance of WindowSizeClass. A new value will be returned whenever a configuration change causes the width or height of the window to cross one of the three breakpoints, for example when the device is rotated or the window is resized.

WindowSizeClass has two important properties, widthSizeClass and heightSizeClass. They hold the size classes for the width and height of the window, WindowWidthSizeClass and WindowHeightSizeClass.

Here's a simple example that shows how to utilize the new composable. It was taken from Googles documentation.

import androidx.activity.compose.setContent
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass

class MyActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    setContent {
      val windowSizeClass = calculateWindowSizeClass(this)
      val useNavRail = windowSizeClass.widthSizeClass > WindowWidthSizeClass.Compact
      MyScreen(useNavRail = useNavRail)
Enter fullscreen mode Exit fullscreen mode

So, what's happening here? If the screen width is at least Medium, we tell the MyScreen() composable to show a Navigation Rail, a Material Design component designed for large screens. It features a navigation bar that runs vertically along the left screen border.

If you have been following the previous installments of this series, this in a way sounds familiar. But I did not mention that new library, did I?


That's because Window size classes are also defined somewhere else.

Jetpack WindowManager (androidx.window:window) has a WindowSizeClass class, too (it's inside package androidx.window.core.layout). I am using its compute() function in my article Code your UI.

So, what's the difference?

Fortunately, not much. While the breakpoints in Jetpack WindowManager classes are named COMPACT, MEDIUM, and EXPANDED (and have a @JvmField annotation), the androidx.compose.material3.windowsizeclass implementations are called Compact, Medium, and Expanded. Obviously, the values in density independent pixels are the same.

Which one should you use?

Well, I strongly advocate supporting foldable devices. If you do, you will likely need Jetpack WindowManager anyway. And if you also use my code snippets, you get the Window sizes class values in a nicely wrapped data class. I will expand on how to utilize Window size classes to define your app layout in the next part of this series.

Unless mentioned otherwise all images are (c) Thomas Künneth

Top comments (2)

erdo profile image
Eric Donovan

This series has been brilliant by the way, it'll be my reference when I start building foldable apps :)

I've not been too impressed with the WindowSizeClass implementation that Android is providing though (I'm in the middle of writing an article about it). They seem a bit trivial to me and not that well thought through.

It's quite difficult to get a design team to change how they think about the designs they provide us, and getting them to redo their assumptions again 6 months later because someone in the android team decided to re-think their hard coded breaks points really makes me nervous

tkuenneth profile image
Thomas Künneth

Eric, thanks a lot for your kind words about the series.

I see your points regarding the WindowSizeClass implementations. In a way, I treat them as "switches" that toggle broad app layout, for example bottombar navigation vs. Navigation Rail. Or: show top appbar vs. don't show top app bar. :-) But they also influence inner app layout. The important topic here is canonical layouts, which will be the topic of the final part.