A new angle on Flutter

Andrei Diaconu

Hello Flutter developers!

Today we are taking a closer look at the hinge on Microsoft Surface Duo and other foldable devices. The hinge holds the two parts of the device together, but it also has a sensor inside which tells us about the angle between the two screens.

Surface Duo hinge in action
Figure 1: Surface Duo Hinge in action

Hinge angle vs device posture

The hinge angle is already used to calculate the device posture, which is exposed using MediaQuery. The MediaQuery update is included in the Flutter foldable support we blogged about previously, and which is currently in review. For example, the “half-opened” posture corresponds to hinge angles around 90 degrees. If the posture is enough for your app to provide a better experience, we recommend using it instead of the angle coming from the sensor directly.

There are situations where the hinge angle itself is important for your app. This raw data is not part of MediaQuery, as this would update your whole app too often. It is instead provided as part of the dual_screen Flutter plugin.

Hinge angle values

Surface Duo has a hinge that supports the whole 0 to 360 degrees range of movement. You can develop and test your app using other foldable devices and emulators, but keep in mind they usually have a limited range of movement, either below 180 degrees or above 180 degrees. To make better sense of what these values mean, here are four important example angles:

  • 0 – Screens are facing each other, and not visible. Device is closed.
  • 90 – Device is an “L” shape with the screens on the inside. Posture is “half-opened”.
  • 180 – Device is flat. Screens are facing the same direction. Posture is “flat”.
  • 360 – Screens are facing opposite directions and only one screen is operating. Since only one screen is operating, the device now behaves as a single-screen device and postures are no longer reported in MediaQuery.

Reading the angle in Flutter

Add dual_screen to your pub.dev dependencies section.

    dual_screen: ^1.0.0

Import and use in your dart files.

  import 'package:dual_screen/dual_screen_info.dart';
  DualScreenInfo.hingeAngleEvents.listen((double hingeAngle) {
  DualScreenInfo.hasHingeAngleSensor.then((bool hasHingeSensor) {

You now have access to two new static properties:

  • hingeAngleEvents – Broadcast stream of events from the device hinge angle sensor. If the device is not equipped with a hinge angle sensor, the stream produces no events.
  • hasHingeAngleSensor – Future returning true if the device has a hinge angle sensor. Alternatively, if your app already uses MediaQuery.displayFeatures or MediaQuery.hinge to adapt to foldable or dual-screen form factors, you can safely assume the hinge angle sensor exists and that hingeAngleEvents produces usable values.

Sample app

There is a sample app available on the dual_screen GitHub page. You can test the sample app using the regular foldable emulators available in Android Studio or using the Surface Duo emulator. The Surface Duo emulator is the only one with two separate screens.

Surface Duo Emulator running the sample app with 149 degrees on the hinge angle
Figure 2: Surface Duo Emulator running the sample app with 149 degrees on the hinge angle

Figure 3: Android Studio Emulator running the sample app with 187 degrees on the hinge angle

Feedback and resources

Check out the Surface Duo developer documentation and past Flutter blog posts for links and details on all our samples. You can find our Flutter samples on GitHub.

If you have any questions, or would like to tell us about your apps, use the feedback forum or message us on Twitter @surfaceduodev.


Discussion is closed.

Feedback usabilla icon