Jetpack Window Manager for foldable devices

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.

Jetpack Window Manager (currently in beta) provides a standard API for working with all foldable devices. It contains two important classes:

  • DisplayFeature - Identifies disruptions in the continuous flat screen surface such as hinges or folds. Window Manager will return a collection of display features from a layout change callback.
  • FoldingFeature - Provides information about a specific feature of the device - while the Surface Duo only has one folding feature, it's possible that other devices might have more. The FoldingFeature class provides information about the state of that part of the device, with properties for bounds, occlusionType, orientation, state, and isSeparating.

A similar guide is on Codelab. Read more about developing for foldables in the Android docs. Examples by the Android team are also available on GitHub. Jetpack release notes record changes in Window Manager as it is updated.

Tip

The controls and helper classes in the Surface Duo dual-screen library work with Window Manager. Follow the instructions to add the correct packages to your app project.

To use the Window Manager directly in your code, follow the instructions below:

Add dependencies

To add the Jetpack Window Manager library, update your build.gradle file.

  1. Ensure the project is compiling with API level 31:

    compileSdk 31
    
  2. Add these dependencies so we can access the APIs needed:

    dependencies {
        implementation "androidx.window:window:1.0.0-beta02"
        implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03'
    }
    

Note

The library name includes "beta" - the Window Manager APIs are currently still in preview and could change prior to becoming stable.

Use Window Manager in your Kotlin code

  1. In the MainActivity class, declare a variable for the window manager:

    class MainActivity : AppCompatActivity() {
       private lateinit var windowInfoRepo: WindowInfoRepository
    

    Ensure that import androidx.window.WindowInfoRepository is added to the top of the file.

  2. Initialize the window manager in your activity's onCreate:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        windowInfoRepo = windowInfoRepository()
    

    Ensure that import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository is added to the top of the file.

  3. Also in the onCreate method, wire up this . The activity should have a TextView called layout_change_text so that this method can update the displayed text:

        lifecycleScope.launch(Dispatchers.Main) {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                windowInfoRepo.windowLayoutInfo
                    .collect { newLayoutInfo ->
                       layout_change_text.text = "No display features detected"
                        for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) {
                            if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.NONE) {
                                layout_change_text.text = "App is spanned across a fold"
                            }
                            if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.FULL) {
                                layout_change_text.text = "App is spanned across a hinge"
                            }
                        }
                    }
            }
        }
    
    

    Ensure that these imports are added to the top of the file:

    import androidx.lifecycle.Lifecycle
    import androidx.lifecycle.lifecycleScope
    import androidx.lifecycle.repeatOnLifecycle
    import androidx.window.layout.DisplayFeature
    import androidx.window.layout.FoldingFeature
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.flow.collect
    import kotlinx.coroutines.launch
    

    Note

    The WindowLayoutInfo class has a collection of DisplayFeature items, one or more of which could be instances of FoldingFeature. Folding feature instances have properties for bounds, occlusionType, orientation, state, and isSeparating that you can query to make decisions about how to adjust your layout for the new state.

  4. When this code is run, the activity will update with the current device posture and display features (if spanned across the fold or hinge). Add additional code to check for more information in the FoldingFeature object.

Samples

The surface-duo-jetpack-window-manager-samples GitHub repository contains a number of Kotlin samples demonstrating different dual-screen user experience patterns built using Jetpack Window Manager.

Java API

Refer to the Jetpack Window Manager alpha10 update blog post and this Java sample to see how to access the WindowInfoRepository class via the WindowInfoRepositoryCallbackAdapter.

Resources