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?) {
super.onCreate(savedInstanceState)
setContent {
val windowSizeClass = calculateWindowSizeClass(this)
val useNavRail = windowSizeClass.widthSizeClass > WindowWidthSizeClass.Compact
MyScreen(useNavRail = useNavRail)
}
}
}
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?
No.
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)
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
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.