{"id":1059,"date":"2020-11-19T10:21:30","date_gmt":"2020-11-19T18:21:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=1059"},"modified":"2020-11-19T12:46:01","modified_gmt":"2020-11-19T20:46:01","slug":"fluent-ui-android-dual-screen","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/fluent-ui-android-dual-screen\/","title":{"rendered":"Fluent UI for Microsoft Surface Duo"},"content":{"rendered":"<p>\n  Hello Kotlin and Java developers,\n<\/p>\n<p>\n  I\u2019m pleased to present our first release of Fluent UI Android controls for Surface Duo. Fluent UI is a user experience framework to help you build attractive apps that are consistent across Android and other platforms. <a href=\"https:\/\/developer.microsoft.com\/fluentui#\/\" target=\"_blank\" rel=\"noopener noreferrer\">Read more about Fluent UI<\/a>.\n<\/p>\n<p>\n  To help developers build dual-screen apps we have enhanced many of the Fluent UI Android layouts and controls to be dual-screen aware.\n<\/p>\n<h2>Fluent UI for Surface Duo<\/h2>\n<p>\n  There are nine Fluent UI controls that have been enhanced for dual-screen devices:\n<\/p>\n<table>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/appbarlayout?WT.mc_id=docs-surfaceduoblog-conceptdev\">AppBarLayout<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Search input box does not extend under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/bottomsheet?WT.mc_id=docs-surfaceduoblog-conceptdev\">BottomSheet<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Always appears on the right screen, and never under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/calendarview?WT.mc_id=docs-surfaceduoblog-conceptdev\">CalendarView<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Can be spanned under hinge and day columns adjust\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/drawer?WT.mc_id=docs-surfaceduoblog-conceptdev\">Drawer<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Drawer appears on a single screen\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/peoplepickerview?WT.mc_id=docs-surfaceduoblog-conceptdev\">PeoplePickerView<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Persona chips will avoid being placed under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/datetimepicker?WT.mc_id=docs-surfaceduoblog-conceptdev\">DateTimePicker<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Popups will not appear under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/popupmenu?WT.mc_id=docs-surfaceduoblog-conceptdev\">PopupMenu<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Menus will avoid appearing under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/snackbar?WT.mc_id=docs-surfaceduoblog-conceptdev\">Snackbar<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  The snackbar will only show on a single screen, and not appear spanned under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/tooltip?WT.mc_id=docs-surfaceduoblog-conceptdev\">Tooltip<\/a><\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  Tooltips avoid appearing under the hinge\n<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n  You can add the controls to your app by <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/?WT.mc_id=docs-surfaceduoblog-conceptdev#configure-your-project\">updating your <strong>build.gradle<\/strong> file<\/a>, and read more details in the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/?WT.mc_id=docs-surfaceduoblog-conceptdev\">dual-screen documentation<\/a>.\n<\/p>\n<h2>Enhanced control examples<\/h2>\n<p>\n  The <a href=\"https:\/\/github.com\/microsoft\/fluentui-android\/tree\/master\/FluentUI.Demo\">Fluent UI sample app<\/a> available on GitHub is also dual-screen enhanced: when you span the app across both screens the control list is filtered to show only enhanced controls:\n<\/p>\n<p>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/menu-framed-400.png\" alt=\"Surface Duo Fluent UI demo app\" width=\"400\" height=\"312\" class=\"alignnone size-full wp-image-1072\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/menu-framed-400.png 400w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/menu-framed-400-300x234.png 300w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><br\/><em>Figure 1: Demo app filters control list to show only enhanced controls when spanned<\/em>\n<\/p>\n<p>\n  This makes it easy to explore the different dual-screen options available in Fluent UI, including the controls shown below.\n<\/p>\n<h3>AppBarLayout<\/h3>\n<p>\n  The sample itself is contained in a dual-screen enhanced <code>AppBarLayout<\/code> control, which is declared in the <strong>activity_demo_list.xml<\/strong> layout, like this:\n<\/p>\n<pre>&lt;com.microsoft.fluentui.appbarlayout.AppBarLayout\r\n    android:id=\"@+id\/app_bar\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\" \/><\/pre>\n<p>\n  The key enhancement of the AppBarLayout is that the search input box does not display under the hinge:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-9.png\" class=\"wp-image-1061\" width=\"400\" alt=\"Surface Duo showing the app bar layout\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-9.png 637w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-9-300x235.png 300w\" sizes=\"(max-width: 637px) 100vw, 637px\" \/><br \/><em>Figure 2: AppBarLayout spanned across two screens<\/em>\n<\/p>\n<p>\n  There are a number of additional display options (such as the scrolling behavior, back button visibility, and theme). See the <strong>AppBarLayoutActivity.kt<\/strong> file for example implementation details.\n<\/p>\n<h3>Snackbar<\/h3>\n<p>\n  Snackbars are a convenient way for the app to inform the user or get their (optional) input. The Fluent UI <code>Snackbar<\/code> does this while avoiding being drawn under the hinge. A simple snackbar with an action button can be shown with this code:\n<\/p>\n<pre>val snackbar = Snackbar.make(root_view, \"This is a multiline snackbar. Max lines are set to two\", Snackbar.LENGTH_INDEFINITE)\r\n    .setAction(\"Action\", View.OnClickListener {\r\n        \/\/ handle click here\r\n    })\r\nsnackbar.show()<\/pre>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-10.png\" class=\"wp-image-1062\" width=\"400\" alt=\"Surface Duo showing snackbar\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-10.png 633w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-10-300x235.png 300w\" sizes=\"(max-width: 633px) 100vw, 633px\" \/>\n  <br \/><em>Figure 3: Snackbar only appears on a single screen<\/em>\n<\/p>\n<p>\n  Various other options are demonstrated in the <strong>SnackbarActivity.kt<\/strong> file included in the sample<strong>.<\/strong>\n<\/p>\n<h3>DateTimePicker<\/h3>\n<p>\n  This control shows a popup date and time picker, which is centered on a single screen, but shifts to the right when the application is spanned. Here\u2019s a code snippet from the sample app that will show the picker:\n<\/p>\n<pre>val dateTimePicker = DateTimePicker.newInstance(\r\n    this,\r\n    picker.mode,\r\n    picker.dateRangeMode,\r\n    getFragmentDateTime(),\r\n    getFragmentDuration()\r\n)\r\ndateTimePicker.show(supportFragmentManager, picker.tag)<\/pre>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-11.png\" class=\"wp-image-1063\" width=\"400\" alt=\"Surface Duo showing date time picker\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-11.png 631w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/11\/word-image-11-300x234.png 300w\" sizes=\"(max-width: 631px) 100vw, 631px\" \/>\n  <br \/><em>Figure 4: DateTimePicker does not appear under the hinge<\/em>\n<\/p>\n<p>\n  The actual popup is configurable for dates, times, or a date\/time range.\n<\/p>\n<h3>Other enhanced controls<\/h3>\n<p>\n  There are six other enhanced controls included in the Fluent UI Android package. View the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/fluent-ui\/?WT.mc_id=docs-surfaceduoblog-conceptdev\">dual-screen Fluent UI documentation<\/a> for more examples and code-snippets to learn more.\n<\/p>\n<h2>Best Inventions of 2020<\/h2>\n<p>It was exciting to see Time magazine included the <a href=\"https:\/\/time.com\/collection\/best-inventions-2020\/5911343\/microsoft-surface-duo\/\">Surface Duo in their Best Inventions of 2020<\/a> list. They recognized the dual-screen form factor was \u201ca glimpse into the future of mobile computing\u201d.\n<\/p>\n<h2>Feedback<\/h2>\n<p>\n  We\u2019d love to hear how about the apps you\u2019re building for dual-screen devices and how Fluent UI can help. Download the demo or review the source code on the <a href=\"https:\/\/github.com\/microsoft\/fluentui-android\">FluentUI-Android GitHub repo<\/a>, and raise an <a href=\"https:\/\/github.com\/microsoft\/fluentui-android\/issues\">issue<\/a> if you have a question. \n<\/p>\n<p>\n  Please reach out to the Surface Duo Developer Experience team using the <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a> or <a href=\"https:\/\/twitter.com\/surfaceduodev\">Twitter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Kotlin and Java developers, I\u2019m pleased to present our first release of Fluent UI Android controls for Surface Duo. Fluent UI is a user experience framework to help you build attractive apps that are consistent across Android and other platforms. Read more about Fluent UI. To help developers build dual-screen apps we have enhanced [&hellip;]<\/p>\n","protected":false},"author":45842,"featured_media":1063,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[365,704,705,473,45],"class_list":["post-1059","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-android-developer","tag-fluent-ui","tag-java","tag-kotlin","tag-surface-duo-sdk"],"acf":[],"blog_post_summary":"<p>Hello Kotlin and Java developers, I\u2019m pleased to present our first release of Fluent UI Android controls for Surface Duo. Fluent UI is a user experience framework to help you build attractive apps that are consistent across Android and other platforms. Read more about Fluent UI. To help developers build dual-screen apps we have enhanced [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1059","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\/45842"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=1059"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1059\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/1063"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=1059"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=1059"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=1059"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}