{"id":1518,"date":"2021-05-06T13:01:55","date_gmt":"2021-05-06T20:01:55","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=1518"},"modified":"2021-05-06T14:54:24","modified_gmt":"2021-05-06T21:54:24","slug":"dual-screen-xamarin-forms-animation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/dual-screen-xamarin-forms-animation\/","title":{"rendered":"Creating beautiful dual-screen Xamarin.Forms apps"},"content":{"rendered":"<p>\n  Hello .NET developers!\n<\/p>\n<p>\n  The blog has previously featured tips for <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/bring-your-xamarin-apps-to-surface-duo\/?WT.mc_id=blog-surfaceduoblog-conceptdev\">bringing Xamarin apps to Surface Duo<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/xamarin-developer-training-on-microsoft-learn\/?WT.mc_id=blog-surfaceduoblog-conceptdev\">Microsoft Learn training to help enhance Xamarin apps<\/a>. In this post we\u2019ll discuss changes to animated layouts in a Xamarin.Forms app to adapt them for Microsoft Surface Duo.\n<\/p>\n<h2>Adapt a design for Xamarin<\/h2>\n<p>\n  The sample project is an implementation of this <a href=\"https:\/\/dribbble.com\/shots\/6727910-Mountain-Mobile-Animation\">Dribbble contribution<\/a> by <a href=\"https:\/\/dribbble.com\/henryjackprice\">Henry Price<\/a>. The Xamarin.Forms code developed by <a href=\"https:\/\/www.twitch.tv\/kymphillpotts\">Kym Philpotts<\/a> on his Twitch stream is <a href=\"https:\/\/github.com\/kphillpotts\/MountainMobile\">available on GitHub<\/a>, and the result is demonstrated in the following two animations:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"800\" height=\"600\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-application-description.gif\" class=\"wp-image-1519\" alt=\"Animation of dribbble design in portrait mode\" \/><br\/><em>Figure 1: Single-screen portrait layout and animation<\/em>\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"800\" height=\"600\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/landscape-design.gif\" class=\"wp-image-1520\" alt=\"Animation of dribbble design in landscape mode\" \/><br\/><em>Figure 2: Single-screen landscape layout and animation<\/em>\n<\/p>\n<p>\n  You can watch the code being created on <a href=\"https:\/\/www.youtube.com\/playlist?list=PLBOg2Yf7J2SNxJJNJ517E42nRyuECYN79\">YouTube<\/a>. The key to creating these effects is combining SkiaSharp and animation APIs, along with proportionally sizing elements to work on many different screen sizes.\n<\/p>\n<h2>Enhancing for dual-screens<\/h2>\n<p>\n  When displayed on a single screen of Surface Duo (either portrait or landscape), the existing layout works as expected.\n<\/p>\n<p>\n  Taking inspiration from the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/design\/?WT.mc_id=docs-surfaceduoblog-conceptdev\">Surface Duo user experience design guidelines<\/a>, it seems like the existing portrait design still works well for the dual-landscape posture, but the existing landscape can be improved; rather than the navigation arrows and paging indicator being centered on the left screen, we could snap them to the hinge to create a layout that feels more natural on Surface Duo.\n<\/p>\n<p>\n<a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/old-framed-markup-600.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/old-framed-markup-600.png\" alt=\"Surface Duo showing original dribbble design, with red circles highlight areas to fix\" width=\"600\" height=\"465\" class=\"alignnone size-full wp-image-1526\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/old-framed-markup-600.png 600w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/old-framed-markup-600-300x233.png 300w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a>\n<\/p>\n<p><em>Figure 3: Existing landscape layout on Surface Duo \u2013 maybe we can snap elements to the hinge\u2026<\/em>\n<\/p>\n<p>\n  To update the layout for dual-screen devices:\n<\/p>\n<ol>\n<li>\n  Add <strong>Xamarin.Forms.DualScreen<\/strong> NuGet to the solution.\n<\/li>\n<li>\n  In the Android project, initialize the support for dual-screen devices:\n  <\/p>\n<pre>Xamarin.Forms.DualScreen.DualScreenService.Init(this);<\/pre>\n<\/li>\n<li>\n  Where code tweaks are required, add:\n  <\/p>\n<pre>using Xamarin.Forms.DualScreen;<\/pre>\n<\/li>\n<li>\n  Use <\/p>\n<pre>DualScreenInfo.Current<\/pre>\n<p> to discover information about the device posture and screen and hinge coordinates to update the layout accordingly. The existing layouts being responsive to screen sizes makes the changes easier.\n<\/li>\n<\/ol>\n<p>\n  For example, to adapt the image boundary to snap to the hinge, detect when the app is spanned across both screens in dual-portrait, and change the element:\n<\/p>\n<pre>if (DualScreenInfo.Current.SpanMode == TwoPaneViewMode.Wide) {\r\n    var paneWidth = DualScreenInfo.Current.HingeBounds.X;\r\n    landscapeGrid.ColumnDefinitions[0].Width = paneWidth + 60;\r\n    landscapeBoxView.Margin = new Thickness(0, 0, -30, 0);\r\n} else { \/\/ use the existing layout all other times\r\n    landscapeGrid.ColumnDefinitions[0].Width = 225;\r\n    landscapeBoxView.Margin = new Thickness(-70, 0, -30, 0);\r\n}<\/pre>\n<p>\n  After tweaking a few coordinates when the hinge is detected, the app adapts when spanned across two screens:\n<\/p>\n<p>\n<a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/device-animation5.gif\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/device-animation5.gif\" alt=\"Animation of flipping through options on Surface Duo in single and dual-screen modes\" width=\"700\" height=\"544\" class=\"alignnone size-full wp-image-1529\" lowsrc=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/new-framed-700.png\" \/><\/a><br\/><em>Figure 4: Dual-screen enhanced layout snaps elements to hinge<\/em>\n<\/p>\n<p>\n  The dual-screen design \u2013 snapping the image border to the hinge \u2013 might not be the one you would choose but understanding the principles of detecting dual-screen devices and tweaking responsive layouts will help you implement your own dynamic designs across platforms and device form-factors.\n<\/p>\n<h2>Join us at Microsoft Build<\/h2>\n<p>\n  We invite you to join us at\u00a0<a href=\"https:\/\/mybuild.microsoft.com\/\" target=\"_blank\" rel=\"noopener\">Microsoft Build<\/a>\u00a0on May 25-27, a free online developer event. This unique event brings together developers to help the world solve new challenges\u2014sharing knowledge and staying connected is more important than ever. Join your community to learn, connect, and code\u2014to expand your skillset today, and innovate for tomorrow.\n<\/p>\n<p>\n  <a href=\"https:\/\/mybuild.microsoft.com\/\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" width=\"1087\" height=\"190\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-text-description-automa.png\" class=\"wp-image-1523\" alt=\"Microsoft Build free online conference banner, May 25-27, 2021\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-text-description-automa.png 1087w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-text-description-automa-300x52.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-text-description-automa-1024x179.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/05\/graphical-user-interface-text-description-automa-768x134.png 768w\" sizes=\"(max-width: 1087px) 100vw, 1087px\" \/><\/a>\n<\/p>\n<h2>Resources and feedback<\/h2>\n<p>\n  The original Xamarin.Forms source code is available on <a href=\"https:\/\/github.com\/kphillpotts\/MountainMobile\">GitHub<\/a>, and the dual-screen enhancements are <a href=\"https:\/\/github.com\/conceptdev\/MountainMobile\">available too<\/a>. You can watch the original code being written on <a href=\"https:\/\/www.youtube.com\/playlist?list=PLBOg2Yf7J2SNxJJNJ517E42nRyuECYN79\">Kym&#8217;s YouTube playlist<\/a>.\n<\/p>\n<p>\n  Check out the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/xamarin\/?WT.mc_id=docs-surfaceduoblog-conceptdev\">Surface Duo developer documentation for Xamarin<\/a> for links and details on all our samples. You can also find them summarized in the <a href=\"https:\/\/docs.microsoft.com\/samples\/browse\/?expanded=surface&#038;products=surface-duo&#038;WT.mc_id=docs-surfaceduoblog-conceptdev\">Microsoft Samples Browser<\/a>, or explore on <a href=\"https:\/\/github.com\/microsoft\/surface-duo-app-xamarin-samples\">GitHub<\/a>.\n<\/p>\n<p>\n  If you have any questions, or would like to tell us about your apps, use the <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  You can also join the <a href=\"https:\/\/www.twitch.tv\/surfaceduodev\">Surface Duo Developer Experience team live on Twitch<\/a> at 11am PDT tomorrow to chat about this project, and follow <a href=\"https:\/\/www.twitch.tv\/kymphillpotts\">Kym on Twitch<\/a> too.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello .NET developers! The blog has previously featured tips for bringing Xamarin apps to Surface Duo and Microsoft Learn training to help enhance Xamarin apps. In this post we\u2019ll discuss changes to animated layouts in a Xamarin.Forms app to adapt them for Microsoft Surface Duo. Adapt a design for Xamarin The sample project is an [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":1528,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[709,694,181,182],"class_list":["post-1518","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-design","tag-user-experience","tag-xamarin","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Hello .NET developers! The blog has previously featured tips for bringing Xamarin apps to Surface Duo and Microsoft Learn training to help enhance Xamarin apps. In this post we\u2019ll discuss changes to animated layouts in a Xamarin.Forms app to adapt them for Microsoft Surface Duo. Adapt a design for Xamarin The sample project is an [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1518","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\/570"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=1518"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1518\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/1528"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=1518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=1518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=1518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}