{"id":552,"date":"2020-07-30T12:00:31","date_gmt":"2020-07-30T19:00:31","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=552"},"modified":"2020-09-24T10:55:22","modified_gmt":"2020-09-24T17:55:22","slug":"new-dual-screen-controls-preview","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/new-dual-screen-controls-preview\/","title":{"rendered":"New dual-screen controls preview"},"content":{"rendered":"<p>\n  Hello Microsoft Surface Duo Android developers!\n<\/p>\n<p>\n  This week we\u2019ve updated and refactored our controls to help you build dual-screen applications with less work and more functionality.\n<\/p>\n<p>\n  The classes in the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/introducing-dual-screen-layouts-android\/?WT.mc_id=blog-surfaceduoblog-CristianVerdes\">previous release<\/a> of our library are still available:\n<\/p>\n<ul>\n<li>\n    ScreenHelper\n  <\/li>\n<li>\n    SurfaceDuoScreenManager\n  <\/li>\n<li>\n    SurfaceDuoLayout\n  <\/li>\n<\/ul>\n<p>\n  However, we have re-packaged the controls into separate libraries so they\u2019re easier to add only what you need:\n<\/p>\n<ul>\n<li><strong>Core<\/strong> \u2013 contains ScreenHelper and SurfaceDuoScreenManager. You can use these directly in your code and are also used by the other libraries.\n  <\/li>\n<li><strong>Bottom navigation<\/strong> \u2013 extends the bottom navigation control to fit into one or two screens.\n  <\/li>\n<li><strong>Fragment handler<\/strong> \u2013 contains a helper class to manage fragments on one or two screens.\n  <\/li>\n<li><strong>Layouts <\/strong>\u2013 contains our original SurfaceDuoLayout control, as well as a simpler \u201chelper layout\u201d that will shift a view to the left or right.\n  <\/li>\n<li><strong>Tabs <\/strong>\u2013 extends the tab layout so that the tabs can be positioned across one or two screens.\n  <\/li>\n<\/ul>\n<p>\nEach of the new controls are described below and you can refer to the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">updated documentation<\/a> for more information. You can add them to your project by updating your gradle dependencies according to <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes#declaring-dependencies\">these instructions<\/a>. Samples for each are available alongside the <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk\">open-source code<\/a>. Use our\u00a0<a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\" target=\"_blank\" rel=\"noopener noreferrer\">feedback forum<\/a>\u00a0or the <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk\/issues\">SDK issues list<\/a> to provide feedback on these controls and let us know what else you\u2019d like to see added.\n<\/p>\n<h2>Screen helper<\/h2>\n<p>\nThis <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/core\/screen-helper\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">helper class<\/a> provides functions to query the state of the device, such as the hinge area, the screen rectangles when the app is spanned, and whether the app is spanned. Here\u2019s one example using the screen helper in the code snippet below that demonstrates how to show or hide a control depending on spanned state:\n<\/p>\n<pre>val visibility = if (ScreenHelper.isDeviceSurfaceDuo(this) &&\r\n    ScreenHelper.isDualMode(this)\r\n) { \/\/ isSpanned on a Surface Duo\r\n    View.VISIBLE\r\n} else {\r\n    View.GONE\r\n}\r\n<\/pre>\n<h2>Surface Duo screen manager<\/h2>\n<p>\nThe <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/core\/surfaceduo-screen-manager\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">screen manager<\/a> can be wired up to listen for changes in the app\u2019s state so that your code can respond to events like spanning or unspanning and change the layout accordingly. This code shows a simple example of responding to an application changing from one screen to two (or vice versa):\n<\/p>\n<pre>\/\/ Application subclass\r\nlateinit var surfaceDuoScreenManager: SurfaceDuoScreenManager\r\noverride fun onCreate() {\r\n    super.onCreate()\r\n    surfaceDuoScreenManager = SurfaceDuoScreenManager.getInstance(this)\r\n}\r\n\r\n\/\/ Activity\r\noverride fun onCreate(savedInstanceState: Bundle?) {\r\n    super.onCreate(savedInstanceState)\r\n    setContentView(R.layout.activity_main)\r\n    (application as SampleApp).surfaceDuoScreenManager.addScreenModeListener(\r\n        this,\r\n        object : ScreenModeListener {\r\n            override fun onSwitchToSingleScreen() {\r\n                Toast.makeText(\r\n                    this@MainActivity,\r\n                    \"Single Screen Mode\",\r\n                    Toast.LENGTH_SHORT\r\n                ).show()\r\n            }\r\n            override fun onSwitchToDualScreen() {\r\n                Toast.makeText(\r\n                    this@MainActivity,\r\n                    \"Dual Screen Mode\",\r\n                    Toast.LENGTH_SHORT\r\n                ).show()\r\n            }\r\n        }\r\n    )\r\n}\r\n<\/pre>\n<h2>Bottom navigation<\/h2>\n<p>\n  The default behavior for bottom navigation in a dual-screen view could result in one of the options being obscured by the hinge. The <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/bottomnavigation\/surfaceduo-bottomnavigationview\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">Surface Duo bottom navigation<\/a> has configuration controls to choose which screen to group the navigation options:\n<\/p>\n<ul>\n<li>\n    <code>DisplayPosition.START<\/code>\u00a0&#8211; grouped on first screen.\n  <\/li>\n<li>\n    <code>DisplayPosition.END<\/code>\u00a0&#8211; grouped on second screen.\n  <\/li>\n<li>\n    <code>DisplayPosition.DUAL<\/code>\u00a0&#8211; spanned across both screens (might appear under hinge).\n  <\/li>\n<\/ul>\n<p>\n  <img decoding=\"async\" width=\"697\" height=\"451\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-7.png\" class=\"wp-image-554\" alt=\"Surface Duo emulator showing bottom navigation on the left screen\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-7.png 697w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-7-300x194.png 300w\" sizes=\"(max-width: 697px) 100vw, 697px\" \/>\n<\/p>\n<p><em>Figure 1: bottom navigation shifts the options to one screen<\/em>\n<\/p>\n<h2>Fragment handler<\/h2>\n<p>\n  The <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/fragment-handler\/fragment-manager-state-handler\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">fragment handler<\/a> is a helper class to restore fragments that are needed after a screen transition (such as from single-screen to dual-screen).\n<\/p>\n<h2>Surface Duo layout<\/h2>\n<p>\nThe Surface Duo layout has been described in a <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/introducing-dual-screen-layouts-android\/?WT.mc_id=blog-surfaceduoblog-CristianVerdes\">previous blog post<\/a>, including its <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/introducing-surfaceduolayout-designer-preview-for-android-studio-developers\/?WT.mc_id=blog-surfaceduoblog-CristianVerdes\">design-time support<\/a>. This is our most powerful layout control and lets you define layouts for single-screen and dual-screen and helps manage them as the app changes state. The screenshots below demonstrate some of the different layout\/orientation combinations that are possible, but you can also span a single layout over both screens:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1373\" height=\"1142\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-8.png\" class=\"wp-image-555\" alt=\"Four Surface Duo emulator images with different dual-screen layouts\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-8.png 1373w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-8-300x250.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-8-1024x852.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-8-768x639.png 768w\" sizes=\"(max-width: 1373px) 100vw, 1373px\" \/>\n<\/p>\n<p><em>Figure 2: single and dual-screen layouts<\/em>\n<\/p>\n<h2>Frame layout<\/h2>\n<p>\nThe <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/layouts\/surfaceduo-frame-layout\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">frame layout<\/a> will be helpful for existing apps migrating to dual-screen support asit will move a view to either screen (or allow it to span both). This can be an interim step as you enhance for dual-screen, or a design choice for some modal views in your app. Here\u2019s a screenshot of the frame layout sample where you can interactively shift a view between screens or across the spanned app window:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"716\" height=\"464\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-9.png\" class=\"wp-image-556\" alt=\"Surface Duo emulator showing frame layout on right screen\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-9.png 716w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-9-300x194.png 300w\" sizes=\"(max-width: 716px) 100vw, 716px\" \/>\n<\/p>\n<p><em>Figure 3: frame layout shifts a view to one side<\/em>\n<\/p>\n<h2>Tabs<\/h2>\n<p>\n  Similar to bottom navigation, tab usage on dual-screens might result in some options being hidden by the hinge. The <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/tabs\/surfaceduo-tablayout\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">dual-screen tab layout<\/a> lets you configure the tabs to group on either screen so that all options are visible:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"714\" height=\"461\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-10.png\" class=\"wp-image-557\" alt=\"Surface Duo emulator showing tabs on the right screen\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-10.png 714w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/word-image-10-300x194.png 300w\" sizes=\"(max-width: 714px) 100vw, 714px\" \/>\n<\/p>\n<p><em>Figure 4: tabs shifts the options to one screen<\/em>\n<\/p>\n<h2>Resources and feedback\u00a0<\/h2>\n<p>\n  Visit the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes\">docs<\/a> and <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk\">sample code<\/a> to learn more and try these new controls in your apps. You will notice from the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-library\/?WT.mc_id=docs-surfaceduoblog-CristianVerdes#declaring-dependencies\">gradle configuration<\/a> that these controls are still in alpha\/preview. Please provide us with your feedback on the <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk\">SDK GitHub repo<\/a>.\n<\/p>\n<p>\n  We would also love to hear from you about your overall experience using the SDK, emulator, and what helpers or controls you\u2019d like us to work on next.\u00a0Please reach out using our\u00a0<a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\" target=\"_blank\" rel=\"noopener noreferrer\">feedback forum<\/a>\u00a0or message me\u00a0<a href=\"https:\/\/github.com\/CristianVerdes\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>.\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Microsoft Surface Duo Android developers! This week we\u2019ve updated and refactored our controls to help you build dual-screen applications with less work and more functionality. The classes in the previous release of our library are still available: ScreenHelper SurfaceDuoScreenManager SurfaceDuoLayout However, we have re-packaged the controls into separate libraries so they\u2019re easier to add [&hellip;]<\/p>\n","protected":false},"author":35845,"featured_media":555,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[31,46,45],"class_list":["post-552","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-dual-screen-development","tag-surface-duo","tag-surface-duo-sdk"],"acf":[],"blog_post_summary":"<p>Hello Microsoft Surface Duo Android developers! This week we\u2019ve updated and refactored our controls to help you build dual-screen applications with less work and more functionality. The classes in the previous release of our library are still available: ScreenHelper SurfaceDuoScreenManager SurfaceDuoLayout However, we have re-packaged the controls into separate libraries so they\u2019re easier to add [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/552","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\/35845"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=552"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/552\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/555"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=552"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=552"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=552"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}