{"id":3304,"date":"2023-06-22T17:21:51","date_gmt":"2023-06-23T00:21:51","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=3304"},"modified":"2023-06-22T17:21:51","modified_gmt":"2023-06-23T00:21:51","slug":"jetpack-compose-foldawarecolumn-accompanist","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/jetpack-compose-foldawarecolumn-accompanist\/","title":{"rendered":"Announcing FoldAwareColumn in Accompanist Adaptive"},"content":{"rendered":"<p>\n  Hello Jetpack Compose developers,\n<\/p>\n<p>\n  This week, we\u2019re super excited to announce the release of <code>FoldAwareColumn<\/code>! This new component is part of Accompanist, Google\u2019s \u201csandbox\u201d for experimental Jetpack Compose APIs. The <a href=\"https:\/\/google.github.io\/accompanist\/adaptive\/\">Accompanist Adaptive library<\/a> already contains the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/jetpack-compose-accompanist-twopane\/\"><code>TwoPane<\/code><\/a> component, which we tested out late last year, so <code>FoldAwareColumn<\/code> will be the second component to join the library.\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1427\" height=\"736\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-1.png\" class=\"wp-image-3305\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-1.png 1427w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-1-300x155.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-1-1024x528.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-1-768x396.png 768w\" sizes=\"(max-width: 1427px) 100vw, 1427px\" \/><br\/><em>Figure 1. <code>FoldAwareColumn<\/code> lays out children like a typical <code>Column<\/code> (left) unless a separating fold is present, in which case it places children around the fold to ensure that visuals and controls are accessible (right).<\/em>\n<\/p>\n<h2>Component inspiration<\/h2>\n<p>\n  We first started talking about <code>FoldAwareColumn<\/code> when we met last year at droidcon NYC 2022! The original idea was to create a sheet-like component with an enhancement similar to the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/jetpack-compose-navigation-rail\/#custom-components\">content drawer in our NavigationRail sample<\/a>. The original enhancement dynamically animated sheet content to place around a fold, and the behavior looked like this:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"430\" height=\"550\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/a-screen-shot-of-a-tablet-description-automatical.gif\" class=\"wp-image-3306\" alt=\"A screen shot of a tablet\n\nDescription automatically generated with low confidence\" \/><\/br><em>Figure 2. <code>FoldAwareColumn<\/code> was originally inspired by an enhancement in our Navigation Rail sample, which modified a bottom sheet component to place content around a fold.<\/em>\n<\/p>\n<p>\n  As we prototyped and thought more about potential applications, we realized that creating a <code>FoldAwareColumn<\/code> would be more useful than just making one specific enhanced sheet component. That way, <code>FoldAwareColumn<\/code> can be used inside any other components, like the foundational <code>Row<\/code> or <code>Column<\/code> composables.\n<\/p>\n<p>\n  So, we finally settled on this as the first version of the <code>FoldAwareColumn<\/code> API:\n<\/p>\n<pre>  fun FoldAwareColumn(\r\n      displayFeatures: List&lt;DisplayFeature&gt;,\r\n      modifier: Modifier = Modifier,\r\n      foldPadding: PaddingValues = PaddingValues(),\r\n      horizontalAlignment: Alignment.Horizontal = Alignment.Start,\r\n      content: @Composable FoldAwareColumnScope.() -&gt; Unit,\r\n  )<\/pre>\n<h2>Features<\/h2>\n<p>\n  The main feature of <code>FoldAwareColumn<\/code> is that it has the ability to place children around a separating horizontal fold. As a reminder, <a href=\"https:\/\/developer.android.com\/reference\/kotlin\/androidx\/window\/layout\/FoldingFeature#isSeparating()\"><code>isSeparating<\/code><\/a> returns true when a device with a flexible screen is folded or if the device has a physical hinge\/separation.\n<\/p>\n<p>\n  In addition to this main feature, the first version of <code>FoldAwareColumn<\/code> has similar features to <code>Column<\/code>, as well as some unique features related to fold-aware enhancements:\n<\/p>\n<ul>\n<li>\n    Alignment support\n  <\/li>\n<li>\n    <code>ignoreFold()<\/code> modifier\n  <\/li>\n<li>\n    <code>foldPadding<\/code> parameter\n  <\/li>\n<\/ul>\n<p>\n  Some of these features are made available through <code>FoldAwareColumnScope<\/code>, which is used just like <code>ColumnScope<\/code>.\n<\/p>\n<h3>Alignment support<\/h3>\n<p>\n  Like the original <code>Column<\/code>, <code>FoldAwareColumn<\/code> provides support for setting the horizontal alignment of its children. You can do this either by specifying the <code>horizontalAlignment<\/code> parameter in the composable or by using the <code>align<\/code> and <code>alignBy<\/code> modifiers on children of the layout. These modifiers are made available through <code>FoldAwareColumnScope<\/code>, and you can see an example in Figure 3 of the three different alignment options: <code>Alignment.Start<\/code>, <code>Alignment.CenterHorizontally<\/code>, and <code>Alignment.End<\/code>.\n  \n<\/p>\n<p>\n  At this time, the component does not support weight or arrangement due to the additional complications caused by placing the children around the fold. Because of this, <code>FoldAwareColumn<\/code> will always place children starting from the top of the layout.\n<\/p>\n<h3>Ignore fold modifier<\/h3>\n<p>\n  The <code>ignoreFold()<\/code> modifier is available through <code>FoldAwareColumnScope<\/code>, and it can be used on any children of the layout to make sure they are placed without taking into consideration any folding features. This means that even if a child overlaps a separating fold, it won\u2019t be moved. This can be especially useful when dealing with children that have large height but can be partially occluded, such as images.\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1410\" height=\"978\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-3.png\" class=\"wp-image-3307\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-3.png 1410w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-3-300x208.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-3-1024x710.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/06\/word-image-3304-3-768x533.png 768w\" sizes=\"(max-width: 1410px) 100vw, 1410px\" \/><br\/><em>Figure 3. <code>FoldAwareColumn<\/code> offers support for specifying the horizontal alignment of children, which can be <code>Alignment.Start<\/code> (heart icon), <code>Alignment.CenterHorizontally<\/code> (text), or <code>Alignment.End<\/code> (image). <code>FoldAwareColumnScope<\/code> also gives you access to the <code>ignoreFold()<\/code> modifier, which is used on the image to avoid changing its placement, even when a separating fold is present. <\/em>\n<\/p>\n<h3>Fold padding parameter<\/h3>\n<p>\n  When creating a <code>FoldAwareColumn<\/code>, you can specify the <code>foldPadding<\/code> parameter to add extra space when adjusting the placement of the layout\u2019s children. This fold padding will only be applied when a separating fold is present. The goal of this parameter is to help you follow <a href=\"https:\/\/developer.android.com\/guide\/topics\/large-screens\/make-apps-fold-aware\">foldable design guidelines<\/a>, which suggest that controls and visuals shouldn\u2019t be placed too close to a fold for optimal user experience.\n<\/p>\n<p>\n  The parameter is of type <code>PaddingValues<\/code>, but it\u2019s important to note that only the <code>top<\/code> and <code>bottom<\/code> values of the padding will be taken into consideration, since <code>FoldAwareColumn<\/code> lays out children in a vertical manner.\n<\/p>\n<h2>Add to your project<\/h2>\n<p>\n  To start using <code>FoldAwareColumn<\/code> in your projects, follow these steps:\n<\/p>\n<ol>\n<li>\n<p>Make sure you have the <code>mavenCentral()<\/code> repository in your top-level <b>build.gradle<\/b> file:\n<\/p>\n<pre>  allprojects {\r\n      repositories {\r\n          google()\r\n          mavenCentral()\r\n       }\r\n  }\r\n<\/pre>\n<\/li>\n<li>\n<p>Add dependencies to the module-level <b>build.gradle<\/b> file (current version may be different from what&#8217;s shown here):\n<\/p>\n<pre>  implementation \"com.google.accompanist:accompanist-adaptive:0.31.4-beta\"<\/pre>\n<\/li>\n<li>\n<p>Also ensure the <code>compileSdkVersion<\/code> is set to API 33 and the <code>targetSdkVersion<\/code> is set to API 32 or newer in the module-level <b>build.gradle<\/b> file:\n<\/p>\n<pre>  android { \r\n      compileSdkVersion 33\r\n   \r\n      defaultConfig { \r\n          targetSdkVersion 32\r\n      } \r\n  }\r\n<\/pre>\n<\/li>\n<li>\n  Call <code>FoldAwareColumn<\/code> and pass in all the required parameters: <code>calculateDisplayFeatures<\/code> and the composable content. Optionally, you may also specify a Modifier, the horizontal alignment, and the fold padding, of which only the vertical padding values are used. This can be used to ensure that controls and important UI elements aren\u2019t too close to the fold, which will improve the user experience.\n<\/li>\n<\/ol>\n<p>\n  For more information, check out the <a href=\"https:\/\/google.github.io\/accompanist\/adaptive\/#foldawarecolumn\">API reference<\/a> and <a href=\"https:\/\/github.com\/google\/accompanist\/tree\/main\/sample\/src\/main\/java\/com\/google\/accompanist\/sample\/adaptive\">library samples<\/a>.\n<\/p>\n<h2>Resources and feedback<\/h2>\n<p>\n  All of the code for <code>FoldAwareColumn<\/code> in available on GitHub in the <a href=\"https:\/\/github.com\/google\/accompanist\">Accompanist repo<\/a>. \n<\/p>\n<p>\n  To learn more about Accompanist and enhancing your apps for foldables, check out these resources:\n<\/p>\n<ul>\n<li><a href=\"https:\/\/google.github.io\/accompanist\/\">Accompanist (google.github.io)<\/a>\n  <\/li>\n<li><a href=\"https:\/\/developer.android.com\/guide\/topics\/large-screens\/learn-about-foldables\">Learn about foldables \u00a0|\u00a0 Android Developers<\/a>\n  <\/li>\n<li><a href=\"https:\/\/developer.android.com\/codelabs\/android-window-manager-dual-screen-foldables\">Support foldable and dual-screen devices with Jetpack WindowManager \u00a0|\u00a0 Android Developers<\/a>\n  <\/li>\n<\/ul>\n<p>\n  If you have any questions, use the <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a>, file an issue in the <a href=\"https:\/\/github.com\/google\/accompanist\/issues\">Accompanist issue tracker<\/a>, or message us on <a href=\"https:\/\/twitter.com\/surfaceduodev\">Twitter @surfaceduodev<\/a>.\n<\/p>\n<p>\n  We will be livestreaming about this update next week! You can also check out the <a href=\"https:\/\/youtube.com\/c\/surfaceduodev\">archives on YouTube<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Jetpack Compose developers, This week, we\u2019re super excited to announce the release of FoldAwareColumn! This new component is part of Accompanist, Google\u2019s \u201csandbox\u201d for experimental Jetpack Compose APIs. The Accompanist Adaptive library already contains the TwoPane component, which we tested out late last year, so FoldAwareColumn will be the second component to join the [&hellip;]<\/p>\n","protected":false},"author":72597,"featured_media":3305,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[692,706],"class_list":["post-3304","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-jetpack-compose","tag-jetpack-window-manager"],"acf":[],"blog_post_summary":"<p>Hello Jetpack Compose developers, This week, we\u2019re super excited to announce the release of FoldAwareColumn! This new component is part of Accompanist, Google\u2019s \u201csandbox\u201d for experimental Jetpack Compose APIs. The Accompanist Adaptive library already contains the TwoPane component, which we tested out late last year, so FoldAwareColumn will be the second component to join the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3304","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\/72597"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=3304"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3304\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/3305"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=3304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=3304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=3304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}