February 24th, 2022

Foldable Flutter follow-up

Andrei Diaconu
Senior Software Engineer

How else to start this article other than saying Hello Flutter developers! This is an update on the foldable support we are contributing to Flutter, along with samples and other goodies for you to try out.

Before we dive in, here is a video presenting most of what you are about to read. This is from the Flutter Vikings conference which lasted for two days, but don’t worry, our updates only take 30 minutes of your time. The last part of the video shows me enhancing an existing application.

The current state of PRs

In our last update, we invited you to have a look at the PRs we opened on the Flutter Framework and Engine. We made a lot of progress and are happy to announce that the Engine PR is merged. The initial Framework PR was split into smaller PRs, and some of them have also been merged.

Flutter Foldable PR progress. Image shows that currently there are 3 merged PRs, one PR currently in review and another as being open but not being reviewed yet Figure 1: Flutter foldable PR progress

MediaQuery now has Display Features

Display Features are parts of the display that can be obstructed by hardware features. The hinge on Surface Duo is such a display feature. The news we want to share today is that the MediaQuery PR is now merged.

This means that if you switch over to the master channel on your local Flutter setup, you can now access a property called displayFeatures. Some devices can have multiple display features, not only one, and therefore this new property is a list. Here is the structure of the items in the list:

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

You can, of course, read more about how to use these new MediaQuery capabilities in our documentation. Just know that you can experiment with them now by simply switching to the master channel.

flutter channel master

If you find that your code is always filtering the list of display features to get the hinge, here is an extension method that you can use in your code.

/// Extension method that helps with working with the hinge specifically.
extension MediaQueryHinge on MediaQueryData {
  DisplayFeature? get hinge {
    for (final DisplayFeature e in displayFeatures) {
      if (e.type == DisplayFeatureType.hinge)
        return e;
    }
    return null;
  }
}

DisplayFeatureSubScreen is also merged

When you want to display content on only one screen of Surface Duo, which is the case when showing a dialog, you now have the option of using the DisplayFeatureSubScreen widget. This widget is mostly needed for modal routes and is heavily used in the “Dialogs and popups support” PR. In this sense it is a steppingstone to complete dialog support. If you have custom modal routes in your app, you might want to consider wrapping them with this widget.

class _MyRoute<T> extends PopupRoute<T> {
  @override
  Widget buildPage(...) {
    return DisplayFeatureSubScreen(
      child: _myPageLayout(),
      anchorPoint: Offset.infinite, 
    );
  }
}

This is also available for you now in the same way that MediaQuery is available by switching your Flutter channel.

It is now easier to experiment

Some of our contributions have not yet been merged. If you want to give them a try today, this is now far easier to do compared to when we first proposed these changes. Back then you had to configure a custom Flutter Engine. Things are a lot simpler now.

To use TwoPane and to have dialogs automatically avoid the hinge, today all you need to do is clone our Flutter fork. This process is described in our documentation.

New samples for you to try

Once you use the foldable_support_complete branch from our Flutter fork, you can try our new and shiny samples. These showcase all the design patterns that our team proposes for dual-screen devices. They also show you a few things you can do with dialogs or the hinge angle.

Flutter dual-screen samples. Image shows the surface duo emulator, running the samples app, showing a list of different examples, such as List-Detail and Companion Pane Figure 2: Flutter dual-screen sample in the Surface Duo emulator

Large screen support in samples

In addition to dual-screen, these samples also give you examples of how to scale up these design patterns for large screens in general.

This means that you can run the sample on desktop, resize the app and see how the design patterns behave in different scenarios. The video at the beginning of this article also showcases all the design patterns on both the Surface Duo emulator and desktop.

Desktop screenshot of the samples app. The image shows the Companion Pane design pattern Figure 3: Companion Pane design pattern on the desktop

To give you an example, here is the Companion Pane sample running on desktop. You will notice that the split between panes is not 50-50, but 70-30. The sample still splits the panes along the hinge on Surface Duo but does something different on other form factors. If you’re curious about how that works, all you must do is study the sample.

Flutter and Microsoft

The Flutter team has recently released Flutter 2.10. The most important announcement made with this release is Windows support reaching production quality. Our goal is to be where developers are and provide the best possible experience when developing for Surface Duo and these announcements only bring us all closer together.

Call to action

  1. Switch over to the master Flutter channel and give MediaQuery.displayFeatures and DisplayFeatureSubscreen a try.
  2. If you’re feeling a bit more adventurous, you can also clone the complete support and try out TwoPane and dialogs.
  3. If you have any questions, or would like to tell us about your apps, use the feedback forum or message us on Twitter @surfaceduodev.
  4. Join us live on Twitch to discuss foldable Flutter at 15h00 European time on Friday 25th February, 2022.

Author

Andrei Diaconu
Senior Software Engineer

Enhancing Flutter for dual-screen and foldable devices at Microsoft.

0 comments

Discussion are closed.