WindowState
Important
This article describes functionality and guidance that is in public preview and may be substantially modified before it's generally available. Microsoft makes no warranties, express or implied, with respect to the information provided here.
WindowState is a utility library for Jetpack Compose that helps you easily get details about the window state of dual-screen, foldable and large screen devices. This information is collected using Google's Jetpack Window Manager library.
The WindowState
class provides information as a Compose state, and it includes properties like folding feature position/orientation, window size class, and window mode. The height and width window size classes are measured based on the official Android guidelines, and the current window mode is determined by folding feature and device orientation. As a reminder, window modes are display postures that take advantage of dual-screen and foldable form factors. There are four possible modes: Dual Portrait, Dual Landscape, Single Portrait, and Single Landscape.
Add dependency
Make sure you have mavenCentral() repository in your top level build.gradle file:
allprojects { repositories { google() mavenCentral() } }
Add the following dependency to the module-level build.gradle file (current version may be different from what's shown here):
implementation "com.microsoft.device.dualscreen:windowstate:1.0.0-alpha07"
Also ensure the compileSdkVersion is set to API 33 and the targetSdkVersion is set to API 32 or newer in the module-level build.gradle file.
android { compileSdkVersion 33 defaultConfig { targetSdkVersion 32 } ... }
Use WindowState in your project
To use the library in a Compose project, call the rememberWindowState()
function from your MainActivity. This method returns a WindowState
object that you can pass into your top-level composable as a state.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ExampleAppTheme {
ExampleApp(rememberWindowState())
}
}
}
}
Inside your composables, you can then access the different properties of the WindowState
object to make choices about your app's layout. In the example below, the isDualScreen()
method is used to choose between two different layouts, one for single screen devices and one for dual-screen devices.
fun ExampleApp(windowState: WindowState) {
if (windowState.isDualScreen())
DualScreenAppContent(windowState.foldSizeDp)
else
SingleScreenAppContent()
}
For more detailed API reference information, please refer to the WindowState README.
Calculate pane sizes
Besides exposing Jetpack Window Manager and window size class information, the WindowState
class also calculates pane sizes for two pane layouts. If the TwoPaneLayout component isn't suitable for your project, then you can use the largeScreenPane1Weight
, pane1SizeDp
, and pane2SizeDp
properties to set up your own custom layouts:
fun ExampleApp(windowState: WindowState) {
windowState.largeScreenPane1Weight = 0.3f
CustomListDetailLayout(
pane1Width = windowState.pane1SizeDp.width,
pane2Width = windowState.pane2SizeDp.width,
list = { ListContent() },
detail = { DetailContent() }
)
}
Pane sizes are calculated based on the following logic:
- If a window contains a separating folding feature:
- Calculate pane size based on the boundaries of the folding feature
- If a window is considered large (
EXPANDED
width and at leastMEDIUM
height size classes):- Calculate pane size based on the
largeScreenPane1Weight
property, window size, and device orientation
- Calculate pane size based on the
- If not foldable or large screen:
- Only one pane should be shown, so return pane size 0
Note that these logic checks are performed in order, so it's possible for a large foldable device to be considered a large screen if its folding feature is not separating, meaning the device does not have a hinge and is flat.
Important
The largeScreenPane1Weight
property must be set before calling pane1SizeDp
or pane2SizeDp
for the weight to be used in the calculations.
We recommend using the properties described above to provide support for both large screens and foldables. However, if you only need to use pane sizes when a separating folding feature is present, then you can use the foldablePane1SizeDp
and foldablePane2SizeDp
properties instead:
fun ExampleApp(windowState: WindowState) {
CustomCompanionPaneLayout(
pane1Size = windowState.foldablePane1SizeDp,
pane2Size = windowState.foldablePane2SizeDp,
game = { GameScreen() },
controls = { ControlPanel() }
)
}
Samples
To see more examples of how to use WindowState
, check out the library sample and our Compose samples.