{"id":1344,"date":"2021-03-03T09:46:04","date_gmt":"2021-03-03T17:46:04","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=1344"},"modified":"2021-03-03T09:52:41","modified_gmt":"2021-03-03T17:52:41","slug":"flutter-dual-screen-foldable","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/flutter-dual-screen-foldable\/","title":{"rendered":"Announcing Flutter support for foldable devices"},"content":{"rendered":"<p>\n  Flutter is one of the fastest growing frameworks today and certainly a powerful toolkit for building amazing apps, which is why we\u2019re adding foldable support.\n<\/p>\n<p>\n  Earlier today Microsoft announced a preview of foldable support for Flutter, at Google\u2019s <a href=\"https:\/\/events.flutter.dev\/\">Flutter Engage<\/a>. We love Flutter and foldable devices and want developers to have the best possible experience when working with both. We\u2019re contributing to Flutter to give it foldable capabilities and this article goes into details of what is new. \n<\/p>\n<p>\n  Please note that Foldable support has not yet merged into the Flutter repo. <strong>We first want to listen to your feedback<\/strong>, which you can give on the <a href=\"https:\/\/github.com\/flutter\/flutter\/pull\/77156\">framework PR<\/a> and <a href=\"https:\/\/github.com\/flutter\/engine\/pull\/24756\">engine PR<\/a> before they are closed. Our goal is to empower you to easily build amazing experiences for all foldables.\n<\/p>\n<h2>Types of foldable devices<\/h2>\n<p>\n  There are many types of foldable phones out there already. Some have flexible displays that bend and curl. Microsoft Surface Duo has two separate displays joined by a hinge. In all cases, your app continues to see one larger single screen, with \u201cdisplay features\u201d like the hinge blocking part of the display.\n<\/p>\n<p>\n  <em>Learn more about <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\">Surface Duo<\/a> and how it reimagines productivity. How would your app take advantage of the extra space? To experiment with it, have a look at the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/emulator\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\">Surface Duo emulator<\/a>.<\/em>\n<\/p>\n<p>\n  Display features are areas of the display that can be non-functional or obstructed. Your app is already aware of one type of display feature if you use the <strong>SafeArea<\/strong> widget to avoid display cutouts. The three types of display features that we add support for are the <strong>cutout<\/strong>, <strong>hinge<\/strong>, and <strong>fold<\/strong>.\n<\/p>\n<p>\n  <center><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-notch.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-notch.png\" alt=\"Phone with a notch\" width=\"250\" height=\"132\" class=\"alignnone size-full wp-image-1354\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-notch.png 500w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-notch-300x158.png 300w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/a><\/center>\n<\/p>\n<p>\n  A <strong>cutout<\/strong> sits at the edge of the display and usually houses camera systems.\n<\/p>\n<p>\n   <center><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-surface-duo.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-surface-duo.png\" alt=\"Surface Duo device\" width=\"192\" height=\"150\" class=\"alignnone size-full wp-image-1353\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-surface-duo.png 384w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-surface-duo-300x234.png 300w\" sizes=\"(max-width: 192px) 100vw, 192px\" \/><\/a><\/center>\n<\/p>\n<p>\n  A <strong>hinge<\/strong> is a physical separator between the two displays of the device.\n<\/p>\n<p>\n  <center><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-fold.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-fold.png\" alt=\"Image flutter fold\" width=\"250\" height=\"150\" class=\"alignnone size-full wp-image-1355\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-fold.png 500w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/flutter-fold-300x180.png 300w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/a><\/center>\n<\/p>\n<p>\n  You can view the <strong>fold<\/strong> like a <strong>hinge<\/strong> that has zero width. It tells us where the flexible display has a crease.\n<\/p>\n<p>\n  <em>For a complete reference, learn more from the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/mediaquery\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu#display-features\">display feature documentation<\/a>.<\/em>\n<\/p>\n<h2>New in MediaQuery<\/h2>\n<p>\n  Display features are properties of the display. This kind of information is provided by <strong>MediaQuery<\/strong>. We are adding \n<\/p>\n<ul>\n<li><strong>displayFeatures<\/strong> &#8211; a list of all display features. \n  <\/li>\n<li><strong>hinge<\/strong> &#8211; a simple way of knowing info about the hinge.\n  <\/li>\n<\/ul>\n<p>\n  From the three types of display features, cutout and fold types will be used less often. You already use <strong>SafeArea<\/strong> for avoiding <strong>cutout<\/strong> features and you don\u2019t need to avoid <strong>fold<\/strong> features since the display is continuous.\n<\/p>\n<p>\n  When the device is folded, <strong>MediaQuery<\/strong> changes and your widget is automatically rebuilt.\n<\/p>\n<pre>final hinge = MediaQuery.of(context).hinge;\r\nif (hinge==null) {\r\n   print('No hinge');\r\n} else {\r\n   print('Hinge is ${hinge.bounds.width} logical pixels wide');\r\n}<\/pre>\n<p>\n  <img decoding=\"async\" width=\"1429\" height=\"477\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-description-automaticall.png\" class=\"wp-image-1347\" alt=\"Surface Duo emulators showing a single-screen and a dual-screen app sample\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-description-automaticall.png 1429w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-description-automaticall-300x100.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-description-automaticall-1024x342.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-description-automaticall-768x256.png 768w\" sizes=\"(max-width: 1429px) 100vw, 1429px\" \/>\n<\/p>\n<p>\n  <em>For a complete reference, learn more from the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/mediaquery\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\"><strong>MediaQuery<\/strong> documentation<\/a>.<\/em>\n<\/p>\n<h2>Dialogs and modal routes<\/h2>\n<p>\n  Dialogs show up on the middle of the screen by default. On devices with a hinge, dialogs go on the first screen, which is left for LTR configurations. We added the optional parameter <strong>screen<\/strong> to <strong>showDialog<\/strong> which allows you to override this behavior. Context or popup menus avoid the hinge by default. In double landscape mode, the first screen is the top one.\n<\/p>\n<p>\n  You might have your own modal or popup route classes in your app, which you want to make \u201chinge-aware\u201d. We provide a widget called <strong>HingeAvoidingModalWrapper<\/strong> which you add at the top of your route layout to make it avoid the hinge.\n<\/p>\n<pre>showDialog(\r\n   context: context,\r\n   builder: (_) =&gt; AlertDialog(\r\n      title: Text(\"Hinge Aware Dialog\"),\r\n      content: Text(\"Going on the right screen\"),\r\n   ),\r\n   screen: 1, \/\/ By default, this is 0\r\n);<\/pre>\n<p>\n  <img decoding=\"async\" width=\"1429\" height=\"954\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-application-description.png\" class=\"wp-image-1348\" alt=\"Surface Duo emulator showing sample app with a dialog on the right screen\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-application-description.png 1429w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-application-description-300x200.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-application-description-1024x684.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/graphical-user-interface-application-description-768x513.png 768w\" sizes=\"(max-width: 1429px) 100vw, 1429px\" \/>\n<\/p>\n<p>\n  <em>The above screenshot is taken from Flutter Gallery, which we <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/samples\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\">enhanced to support dual-screen layouts<\/a>. Learn more about making your route hinge-aware by looking at the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/hinge-aware-popup-routes\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\"><strong>HingeAwarePopupRoute<\/strong> documentation<\/a>.<\/em>\n<\/p>\n<h2>TwoPane widget<\/h2>\n<p>\n  In many cases, adapting your layout to support dual-screen devices will be as easy as adding <strong>TwoPane<\/strong>, a widget that shows one or two widgets according to available space. It provides a simple way to scale up your design, not just for two screens, but for larger screens like tablets and desktops as well. This sample should give you a hint of how it works.\n<\/p>\n<pre>Widget build(BuildContext context) {\r\n   return TwoPane(\r\n      pane1: _widgetA(),\r\n      pane2: _widgetB(),\r\n      paneProportion: 0.3,\r\n      panePriority: MediaQuery.of(context).size.width &gt; 500 ? TwoPanePriority.both : TwoPanePriority.pane1,\r\n   );\r\n}<\/pre>\n<p>\n  <img decoding=\"async\" width=\"1431\" height=\"396\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/chart-description-automatically-generated.png\" class=\"wp-image-1349\" alt=\"Three devices, a phone, a Surface Duo, and a tablet, showing the TwoPane widget\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/chart-description-automatically-generated.png 1431w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/chart-description-automatically-generated-300x83.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/chart-description-automatically-generated-1024x283.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/03\/chart-description-automatically-generated-768x213.png 768w\" sizes=\"(max-width: 1431px) 100vw, 1431px\" \/>\n<\/p>\n<p>\n  The <strong>panePriority<\/strong> property makes the phone version show only one of the two panes, since space is limited. If you look at the tablet version, you will notice that widget A takes up only 30% of the screen. This is the value given to <strong>paneProportion<\/strong>. On a dual-screen device, both these properties are ignored, and widget A and B take over one screen each.\n<\/p>\n<p>\n<em><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/twopane-widget\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\"><strong>TwoPane<\/strong><\/a> has many useful properties, and we encourage you to <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/flutter\/twopane-widget\/?WT.mc_id=docs-surfaceduoblog-andreidiaconu\">read the documentation<\/a> to learn more.<\/em>\n<\/p>\n<h2>What\u2019s next<\/h2>\n<p>\n  We want your feedback on the <a href=\"https:\/\/github.com\/flutter\/flutter\/pull\/77156\">framework PR<\/a> and <a href=\"https:\/\/github.com\/flutter\/engine\/pull\/24756\">engine PR<\/a>. We can\u2019t wait to see what Flutter developers build with this new capability. Plus, you can ask questions or tell us about your projects using our <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a> or message us on Twitter <a href=\"https:\/\/twitter.com\/surfaceduodev\">@surfaceduodev<\/a>. \n<\/p>\n<p>\n  Please join the <a href=\"https:\/\/www.youtube.com\/watch?v=ROHP97ctcmE\">Flutter Community Q&amp;A session<\/a> at 9am PST on Thursday, March 4, 2021 (the day after the <a href=\"https:\/\/events.flutter.dev\/\">Flutter Engage<\/a> event) to discuss the foldable enhancements. You can also chat with us on <a href=\"https:\/\/twitch.tv\/surfaceduodev\">Twitch<\/a> on Friday, March 5 at 11am PST, and the Microsoft Learn <a href=\"https:\/\/aka.ms\/thelaunchspacesurfaceduo2\">Launch Space<\/a> on Thursday, March 25 at 1pm PST.<\/p>\n<p>\n  Microsoft is not stopping here. Building amazing apps for foldable devices using Flutter should be easy and fun and our next areas of focus will be navigation, codelabs, and more components to help developers. Your feedback is important for deciding what we will build next.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Flutter is one of the fastest growing frameworks today and certainly a powerful toolkit for building amazing apps, which is why we\u2019re adding foldable support. Earlier today Microsoft announced a preview of foldable support for Flutter, at Google\u2019s Flutter Engage. We love Flutter and foldable devices and want developers to have the best possible experience [&hellip;]<\/p>\n","protected":false},"author":54297,"featured_media":1368,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[31,693,46],"class_list":["post-1344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-dual-screen-development","tag-flutter","tag-surface-duo"],"acf":[],"blog_post_summary":"<p>Flutter is one of the fastest growing frameworks today and certainly a powerful toolkit for building amazing apps, which is why we\u2019re adding foldable support. Earlier today Microsoft announced a preview of foldable support for Flutter, at Google\u2019s Flutter Engage. We love Flutter and foldable devices and want developers to have the best possible experience [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/54297"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=1344"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1344\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/1368"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=1344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=1344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=1344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}