Hello Android developers!
Google recently updated a number of dual-screen and foldable packages βWindow Manager, SlidingPaneLayout, Navigation, and Preference β to release candidate. These components can be used to create unique user experiences on the Microsoft Surface Duo and other foldable devices.
Jetpack Window Manager
The WindowInfoTracker class provides an API for your app to respond each time the layout changes and is affected by a hinge or fold. There are a number of examples in the Window Manager samples repo which use the library as shown here:
-
Add the package in your build.gradle file:
implementation 'androidx.window:window:1.0.0-rc01
-
Get an instance of WindowInfoTracker and then use aΒ lifecycleScopeΒ to collect an updatedΒ WindowLayoutInfoΒ and make changes to the user interface accordingly:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { WindowInfoTracker.getOrCreate(this@MainActivity) .windowLayoutInfo .collect { newLayoutInfo -> for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) { if (displayFeature is FoldingFeature) { // do something with hinge/fold } } } } }
Sliding Pane Layout
See our earlier blog post for details on how SlidingPaneLayout behaves on different devices and postures. To use the latest:
-
Add the package in your build.gradle file:
implementation 'androidx.slidingpanelayout:slidingpanelayout:1.0.0-rc01
-
Add the layout to your view XML
<androidx.slidingpanelayout.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sliding_pane_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- first child --> <!-- second child --> </androidx.slidingpanelayout.widget.SlidingPaneLayout>
Navigation
Jetpack Navigation component also got a new update (2.4.0-rc01) that makes it fold and large-screen aware: the component uses now SlidingPaneLayout internally. Since we already have seen what this component does (just above), itβs easy to see how the Navigation component can benefit of it: we can now navigate from A to B destinations following a list-detail pattern.
On single-screen devices, single-screen mode on Surface Duo, or multi-window mode on other foldable devices, we go from A to B destinations showing independent panes at a time (B overlaps A when visible). But on spanned mode on foldables or large-screen devices with more display area, we can now go from A to B destinations showing both at the same time (showing two panes).
Follow these steps to add foldable-aware navigation to your project:
-
Add the dependency in your build.gradle file:
implementation("androidx.navigation:navigation-fragment-ktx:2.4.0-rc01")
-
We have to create a Fragment that extends from AbstractListDetailFragment and implement onCreateListPaneView to supply custom view for the list pane. Then we provide a custom NavHostFragment by overriding onCreateDetailPaneNavHostFragment where we indicate the navigation path we want to follow.
class TwoPaneFragment : AbstractListDetailFragment() { private lateinit var binding: ListPaneBinding override fun onCreateListPaneView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = ListPaneBinding.inflate(inflater, container, false) return binding.root } override fun onCreateDetailPaneNavHostFragment(): NavHostFragment { return NavHostFragment.create(R.navigation.two_pane_navigation) } ... }
For more information you can have a look at a sample we have created where we showcase an easy-to-follow navigation flow.
Preference
Very similar to what Jetpack Navigation component got in its new update, Jetpack Preference is now fold and large-screen aware too. Its latest update (1.2.0-rc01) uses SlidingPaneLayout internally, and, as you may guess, on foldable and large-screen devices, where there is more display area, preferences are shown in a list-detail manner. Very useful!
Follow these steps to add foldable-aware preferences to your project:
-
Add the dependency in your build.gradle file:
implementation("androidx.preference:preference-ktx:1.2.0-rc01")
-
We have to create a Fragment that extends from PreferenceHeaderFragmentCompat and implement onCreatePreferenceHeader where we will supply preference headers that will be used as the list pane:
class TwoPanePreference : PreferenceHeaderFragmentCompat() { override fun onCreatePreferenceHeader(): PreferenceFragmentCompat { return MainPreferenceFragment() } }
-
We will set them either by calling setPreferenceFromResource or setPreferenceScreen.
class MainPreferenceFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences, rootKey) } }
For more information you can have a look at a sample we have created where we showcase a preference screen scenario that is easy to understand.
Resources and feedback
Check out the Surface Duo developer documentation and past blog posts for links and details on all our samples. You can find our Jetpack Window Manager samples on GitHub.
If you have any questions, or would like to tell us about your apps, use the feedback forum or message us on Twitter @surfaceduodev.
This week the Twitch stream will be live at the Europe-friendly time of 13:00h CET (12 noon GMT) β join the team to chat live about this sample app. The stream will be replayed at our usual time of 11am Pacific time for those in the Americas.
-
Add the dependency in your build.gradle file:
0 comments