Flutter MediaQuery for Surface Duo

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.

MediaQuery is the component you use in Flutter when you want information about the device, like the screen size, display density, text scaling, and so on. The hinge between the displays is considered a part of the display. When your app is spanned, the screen size for it is the whole area of both screens, including the hinge, with the hinge area being reported as a display feature.

New MediaQuery properties

  • displayFeatures -> List<DisplayFeature> - Areas of the display that are obstructed by hardware features.
  • hinge -> DisplayFeature? - [Nullable] Area of the display that is obstructed by the hinge specifically.

Display features

Display features are areas of the display that can be non-functional or obstructed.

class DisplayFeature {
    final Rect bounds;
    final DisplayFeatureType type;
    final DisplayFeatureState state;
}

Properties of a DisplayFeature:

  • bounds - Rect area of the view occupied by this display feature
  • type - Enum for type of display features:
    • hinge - A physical separator between the two displays of the device. Surface Duo has a hinge display feature. Display Feature Type: Hinge
    • fold - View this as a hinge that has zero width. It identifies where the flexible display has a crease. Display Feature Type: Fold
    • cutout - Sits at the edge of the display and usually houses camera systems. Display Feature Type: Cutout
  • state - Enum for posture of display feature, which is populated only for folds and hinges. For cutouts, this is unknown. This closely follows the Posture definition from Android.
    • halfOpened - The foldable device's hinge is in an intermediate position between opened and closed state, there is a non-flat angle between parts of the flexible screen or between physical screen panels.
    • flat - The foldable device is completely open, the screen space that is presented to the user is flat.
    • flipped - The foldable device is flipped with the flexible screen parts or physical screens facing opposite directions.
    • unknown - Posture is unknown, either because it is new and unsupported or, in the case of cutout features, it is not populated.

The hinge property

Of the three types of display features, cutout and fold types will be used less often. You already use SafeArea for avoiding cutout features and you don't need to avoid fold features since the display is continuous. The hinge property was added to MediaQuery as a convenient way to get the hinge without having to filter the displayFeatures list. View it as a shortcut that makes your code easier to read. This is the implementation in Dart:

DisplayFeature? get hinge {
    for (DisplayFeature e in displayFeatures) {
      if (e.type == DisplayFeatureType.hinge) return e;
    }
    return null;
  }

The hinge will be null if the device either does not have a hinge, or if the app is not spanned and so the hinge does not overlap our app. Here's an example of how to know if the screen available to the app has a hinge:

final hinge = MediaQuery.of(context).hinge;
if (hinge==null) {
    print('No hinge');
} else {
    print('Hinge is ${hinge.bounds.width} logical pixels wide');
}

While working with the hinge property makes it easy to adapt your layouts for Surface Duo, using the TwoPane widget can make it even easier to define a layout that scales for Surface Duo, but also for tablet and desktop.