About Window size class libraries
Tags: jetpackcompose, foldable, android
Published: 2023-02-12 13:28:36

With the [first stable version of Material Design 3 for Compose](https://material.io/blog/material-3-compose-stable), 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| &lt; 600 dp| &lt; 480 dp|
|Medium| &lt; 840 dp| &lt; 900 dp|
|Expanded| &ge; 840 dp| &ge; 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](https://developer.android.com/reference/kotlin/androidx/compose/material3/windowsizeclass/package-summary).

```kotlin
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](https://dev.to/tkuenneth/code-your-ui-1b83).

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