Tag Archives: Pixel Fold

Jetpack WindowManager 1.1 is stable!

Posted by Francesco Romano, Developer Relations Engineer on Android

It’s been more than a year since the release of the Jetpack WindowManager 1.0 stable version, and many things have happened in the foldables and large screen space. Many new devices have entered the market, and many new use cases have been unlocked!

Jetpack WindowManager is one of the most important libraries for optimizing your Android app for different form factors. And this release is a major milestone that includes a number of new features and improvements.

Let’s recap all the use cases covered by the Jetpack WindowManager library.

Get window metrics (and size classes!)

Historically, developers relied on the device display size to decide the layout of their apps, but with the availability of different form factors (such as foldables) and display modes (such as multi-window and multi-display) information about the size of the app window rather than the device display has become essential.

The Jetpack WindowManager WindowMetricsCalculator interface provides the source of truth to measure how much screen space is currently available for your app.

Built on top of that, the window size classes are a set of opinionated viewport breakpoints that help you design, develop, and test responsive and adaptive application layouts. The breakpoints have been chosen specifically to balance layout simplicity with the flexibility to optimize your app for unique cases.

With Jetpack Compose, use window size classes by importing them from the androidx.compose.material3 library, which uses WindowMetricsCalculator internally.

For View-based app, you can use the following code snippet to compute the window size classes:

private fun computeWindowSizeClasses() { val metrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this) val widthDp = metrics.bounds.width() / resources.displayMetrics.density val widthWindowSizeClass = when { widthDp < 600f -> WindowSizeClass.COMPACT widthDp < 840f -> WindowSizeClass.MEDIUM else -> WindowSizeClass.EXPANDED } val heightDp = metrics.bounds.height() / resources.displayMetrics.density val heightWindowSizeClass = when { heightDp < 480f -> WindowSizeClass.COMPACT heightDp < 900f -> WindowSizeClass.MEDIUM else -> WindowSizeClass.EXPANDED } }

To learn more, see our Support different screen sizes developer guide.

Make your app fold aware

Jetpack WindowManager also provides all the APIs you need to optimize the layout for foldable devices.

In particular, use WindowInfoTracker to query FoldingFeature information, such as:

  • state: The folded state of the device, FLAT or HALF_OPENED
  • orientation: The orientation of the fold or device hinge, HORIZONTAL or VERTICAL
  • occlusion type: Whether the fold or hinge conceals part of the display, NONE or FULL
  • is separating: Whether the fold or hinge creates two logical display areas, true or false
  • bounds: The bounding rectangle of the feature within the application window (inherited from DisplayFeature)

You can access this data through a Flow:

override fun onCreate(savedInstanceState: Bundle?) { ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { WindowInfoTracker.getOrCreate(this@MainActivity) .windowLayoutInfo(this@MainActivity) .collect { layoutInfo -> // New posture information val foldingFeature = layoutInfo.displayFeatures // use the folding feature to update the layout } } } }

Once you collect the FoldingFeature info, you can use the data to create an optimized layout for the current device state, for example, by implementing tabletop mode! You can see a tabletop mode example in MediaPlayerActivity.kt.

A great place to start learning about foldables is our codelab: Support foldable and dual-screen devices with Jetpack WindowManager.

Show two Activities side by side

Last, but not least, you can use the latest stable Jetpack WindowManager API: activity embedding.

Available since Android 12L, activity embedding enables developers with legacy multi-activiity architectures to display multiple activities from the same application—or even from multiple applications—side-by-side on large screens.

It’s a great way to implement list-detail layouts with minimal or no code changes.

Note: Modern Android Development (MAD) recommends using a single-activity architecture based on Jetpack APIs, including Jetpack Compose. If your app uses fragments, check out SlidingPaneLayout. Activity embedding is designed for multiple-activity, legacy apps that can't be easily updated to MAD.

It is also the biggest change in the library, as the activity embedding APIs are now stable in 1.1!

Not only that, but the API is now richer in features, as it enables you to:

  • Modify the behavior of the split screen (split ratio, rules, finishing behavior)
  • Define placeholders
  • Check (and change) the split state at runtime
  • Implement horizontal splits
  • Start a modal in full window

Interested in exploring activity embedding? We’ve got you covered with a dedicated codelab: Build a list-detail layout with activity embedding.

Many apps are already using activity embedding in production, for example, WhatsApp:

Image of WhatsApp on a large screen device showing activity embedding

And ebay!

Image of Ebay on a large screen device showing activity embedding

Implementing list-details layouts with multiple activities is not the only use case of activity embedding!

Starting from Android 13 (API level 33), apps can embed activities from other apps.

Cross‑application activity embedding enables visual integration of activities from multiple Android applications. The system displays an activity of the host app and an embedded activity from another app on screen side by side or top and bottom, just as in single-app activity embedding.

Host apps implement cross-app activity embedding the same way they implement single-app activity embedding, but the embedded app must opt-in for security reasons.

You can learn more about cross-application embedding in the Activity embedding developer guide.

Conclusion

Jetpack WindowManager is one of the most important libraries you should learn if you want to optimize your app’s user experience for different form factors.

WindowManager is also adding new, interesting features with every release, so keep an eye out for what’s coming in version 1.2.

See the Jetpack WindowManager documentation and sample app to get started with WindowManager today!

The new Pixel Fold & Pixel Tablet are here: optimizing for large screens with the latest stable APIs and tools

Posted by Maru Ahues Bouza, Director, Android Developer Relations

Last month at Google I/O, we announced that Pixel Tablet and Pixel Fold are joining our Pixel family of devices, and this month, as consumers purchase them, they are opening them up and downloading their favorite apps, including perhaps…yours!

We’ve been walking you through a number of optimizations you can make so that your app looks great on large screens, but it boils down to three important design principles to make the most of the extra screen space on large screen Android devices:

  1. Two-pane layouts display content across two columns, showing you more content across the unfolded, larger screen, and allows you to do more without extra taps or losing context
  2. App continuity on foldable phones ensures apps easily transition from folded to unfolded orientations
  3. Responsive layouts resize content and controls as the screen size changes, such as when you use two apps in split-screen mode

Over 50+ Google apps, and many of your other favorite apps have already made the optimizations; we rounded up some of our favorites, like how the team at LINE adapts to a two-pane layout, or how Peloton optimized their app for larger screens, including a new design for foldable phones in tabletop mode. It’s a great time to invest in optimizing for large screens; in fact, great large screen apps will be featured and ranked higher in recommendations in Play.

Some of the latest resources to help you get started for large screens

For the last few weeks, we’ve been diving into the world of large screens with posts to help you get the most out of these devices with your apps, including many of the latest updates from this year’s Google I/O. Here’s a round-up of some of the posts:

This is just a taste of the materials we have to help you get your apps ready for large screens, and there’s even more here. Still want more? We’d love to hear how we can help. We can’t wait to see how great your apps look on Pixel Tablet and Pixel Fold!

Developers guide to Pixel Fold and Pixel Tablet: get your app large screen ready

Posted by Alex Vanyo, Developer Relations Engineer

At Google I/O we announced that Pixel Tablet and Pixel Fold are joining our Pixel family of devices. With pre-orders ongoing, now is the time to update your applications to work great on these devices!

This blog covers two topics: what makes Pixel Fold and Pixel Tablet unique, and how you can test your app on these devices before they are generally available.

What makes Pixel Fold and Pixel Tablet unique?

The good news about Pixel Fold and Pixel Tablet is that, if your app is already optimized for larger screens, you won’t have much to do.

For general large screen developer guidance, start with developer.android.com/large-screens. Additionally, we published a blog post right before I/O with some common do’s and don’ts for large screens. And we published a whole set of videos at I/O for how to optimize your apps for large screens.

Besides the general large screen development guidance, there are a few things that make Pixel Fold and Pixel Tablet unique in the market today:

  1. Pixel Fold unfolds from portrait to landscape (not portrait to portrait)
  2. Pixel Fold rear camera sensor orientation is orthogonal to the inner display orientation
  3. Pixel Tablet has a dock

We’ll go through each of these individually so you know what to look out for when updating your own apps.

Provide a delightful unfold experience

One of the most frequent app issues we encountered during the development of Pixel Fold is apps that don’t account for dynamically going from a portrait to landscape display environment. On Pixel Fold and Pixel Tablet, the user can rotate and fold their device as they choose, and multitask with any app. If an app restricts orientation or resizability, the system places the app into a compatibility mode when the user is using the app in a configuration the app doesn’t support directly. Past assumptions made in your app, like assuming that the app is running fullscreen and it won’t be resized, can cause issues with these new devices.

There are two classes of problems apps experience when a user is unfolding a device:

  • Continuity
  • Layout

Continuity

If you don’t manage and save UI states properly, your user can lose state when going from the folded outer display to the unfolded inner display. This can be extremely frustrating for users. For example, a user might begin filling out a form in an app in a small window in multi-window mode or on the outer display of a foldable and realize the extra screen area of a larger window or screen would be helpful for completing the task. If your app loses state, the user loses all previous form entry data and is forced to start all over. While this is not unique to Pixel Fold (the same bugs would likely occur if your app were resized in multi-window mode), the situation becomes a lot more common on a foldable when the act of going from folded to unfolded is a common occurrence.

The takeaway: make sure you’re saving UI state properly.

Layout

Another issue we see is apps being letterboxed on the inner display, even if they support a landscape layout. We’ve also seen cases where apps can be letterboxed on the Pixel Fold inner display when the device is held in the natural landscape orientation, but rotating the device to portrait and back to landscape can make the apps return to full screen!

All of these bugs originate from “isTablet” boolean logic.

Let’s assume we’re working on an app that uses “isTablet” logic to determine if the activity orientation should be restricted to portrait. We see a lot of developers do this to restrict their layout to portrait on phones, but unlock landscape support on large screen devices. A common way to determine isTablet is to use a smallest-width qualified boolean value (for example, isTablet=true for sw>=600dp) or equivalent code using the WindowMetricsCalculator computeCurrentWindowMetrics APIs.

Let’s walk this logic through the scenario of a user doing the following steps with Pixel Fold:

  1. Open the app on the outer display
  2. With the app still open, unfold the device
  3. Rotate the unfolded device to portrait
  4. Rotate the device back to landscape
Step 1: Open the app on the outer display
In this case, the smallest-width value is < 600dp and reports isTablet=false. The app restricts the activity’s orientation to portrait and the app won’t rotate to landscape on the outer display.

Step 2: Unfold the device
When the device is unfolded (to landscape), the activity’s orientation is still restricted to portrait. Android recognizes this and applies letterboxing to the application so the user doesn’t need to rotate the device to continue using the application. The configuration’s size metrics and the WindowMetricsCalculator computeCurrentWindowMetrics API both return the display metrics of the letterboxed window, not the entire size of the device screen. Therefore, display metrics of the letterboxed window still have the smallest width < 600dp, so isTablet still evaluates to false, meaning the orientation is still restricted to portrait.

Step 3: Rotate the unfolded device to portrait
When the user rotates the inner display to portrait, the application can take advantage of the full display since the activity’s orientation and the display orientation match. In this case, the smallest width is > 600 dp and isTablet evaluates to true. If you have application logic to stop restricting the activity orientation based on these criteria, your activity will no longer be portrait but will instead become unspecified.

Step 4: Rotate back to landscape
Now when you rotate to landscape, the application takes advantage of the entire screen, and there will be no letterboxing. While this is the desired outcome, the steps to get there can be extremely confusing for a user! Users won’t understand why your application is full screen landscape in some cases but not others.

There are two ways to fix this:

  1. Stop restricting activity orientation
  2. Use the Jetpack WindowMetricsCalculator computeMaximumWindowMetrics API to determine the maximum size your window could be on the current display.

We strongly recommend the first way. If your application is functional and usable in landscape on a traditional phone display, we encourage you to not restrict the app to portrait in any situation. Android has an auto-rotation lock feature (and Pixel Fold enables users to specify this setting independently for the outer and inner display), so let the users decide if they want to always use their outer display in portrait or not.

If your app has glaring usability or functional issues on a landscape, traditional phone-size display, then use the WindowMetricsCalculator computeMaximumWindowMetrics API to retrieve the maximum size your app’s window could be if resized. We have a cookbook recipe for this specific use case. However, this should be a temporary solution until you make your landscape layout work everywhere.

Make your camera preview work for all states

Camera preview is a complex topic that’s applicable only if your application uses the camera directly, so we’ll just highlight the problem and make a quick recommendation. For more advanced uses of Android camera, see the in-depth Camera preview guide.

Recommendation: Unless you have advanced Camera API requirements, use the CameraX library, which contains easy-to-use APIs that avoid many of the camera preview orientation concerns described below.

Problem: This is related to the layout issue. Because the outer and inner displays of some foldables have different natural orientations, it can’t be true that both displays match the rear camera sensor orientation. So, one of the displays has to be orthogonal to the camera sensor. For Pixel Fold, this means the inner display natural orientation of landscape is rotated relative to the main camera sensor's natural orientation of portrait.

Images of portrait rear camera preview on protrait outer screen and landscape inner screen of Pixel Fold
Portrait rear camera preview on portrait outer screen and landscape inner screen of Pixel Fold

This can cause difficulty when building camera preview displays if you have previously assumed that the camera orientation always matches your UI orientation. You need to make sure you’re handling rotation logic for the displays and sensor properly so you don’t get a distorted, rotated, or cropped camera preview. If you are also restricting orientation and your app is letterboxed, the orientation of your app may not match the orientation of the device or the orientation of the camera.

There is a lot of depth to this topic, but the Camera preview guide will help you get through this step by step.

Handle the Pixel Tablet dock

Last but not least is the Pixel Tablet charging speaker dock.Outputting sound to the dock is just like outputting to the external speakers, and apps shouldn’t really need to do anything to update for the dock out of the box.

Image showing removing Pixel Tablet from the dock
Removing Pixel Tablet from the dock

Docking and undocking triggers a uiMode configuration change.

Make sure your app works as expected when going from docked to undocked and back.Most apps already handle this gracefully.

This could happen if you are doing something in your application’s onConfigurationChanged handlers that would cause a disruptive experience when a device is docked or not. For example, if your application includes an element that’s playing media or other content, don’t pause playback when onConfigurationChanged is called. Many apps already handle this well and there’s not much to consider. This will be a nuisance to users who may be watching a video on the dock and then want to take it on the go, or who start playing music while holding the tablet and then dock it to use the dock’s better speakers.

Test your apps… today!

Once you’ve updated your application to work great on large screen devices, you can test them in the new Pixel Fold and Pixel Tablet configurations in Android Studio Hedgehog Canary 3 or later. These emulators are great for testing layout, but we are continuing to improve these emulators to serve more features in the future.

Screen grab of API 34 Pixel tablet and Pixel Fold emulators in Android Studio
API 34 Pixel Tablet and Pixel Fold emulators in Android Studio

To test camera preview orientation flexibility, we recommend trying any tablet with your camera preview in multi-window mode and continuously resizing your application window to make sure your camera preview works as expected.

Now is the time to update your applications so they delight users who begin unboxing their Pixel Fold and Pixel Tablet devices later this month!