This post has been republished via RSS; it originally appeared at: Microsoft Developer Blogs - Feed.
Hello Microsoft Surface Duo Developers! Until recently, mobile devices all had one thing in common: a single screen. While applications had to support multiple screen sizes, recently manufacturers got creative and introduced new foldable, dual-screen devices, Google added support for multi-windowing on Android. Now applications need to dynamically handle size changes and various screen sizes. In today’s blog post, I’ll discuss how your Android application will behave on the Surface Duo, by answering the following questions:- Is the activity spanned or running in a single screen?
- If a single screen, is it on the right or left portrait or top or bottom landscape
- Is there an inset from the keyboard?
- How to launch an external activity while spanned, without it taking the whole display
Spanning and Screen Location (questions 1 and 2)
To best support dual-screen devices, activities should support resizing and react to configuration changes, to do that, add these lines to the activity manifest:android:resizeableActivity="true" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"This also means that the activity will not restart every time its size changes. On Surface Duo the following actions will fire configuration change:
- Orientation change – the aspect ratio of the app changes
- Span or un-span – when the user drags the app to span both displays horizontally or vertically
- From the orientation field, find out if the activity is in Landscape or portrait,
- Detect if the user spanned the activity by using the ScreenHelper.isDualMode helper method
- Then use the getLocationOnScreen to find out the absolute coordinates of our window.
@Override public void onConfigurationChanged (Configuration newConfig){ super.onConfigurationChanged(newConfig); boolean isSpanned = ScreenHelper.isDualMode(MainActivity.this); int screenPosition[] = new int [2]; getWindow().getDecorView().getLocationOnScreen(screenPosition); }Using this information, I can answer question 1 and 2:
Spanned | Not Spanned | |||
---|---|---|---|---|
Landscape |
|
|||
Portrait |
|
Table: 6 different configuration an activity can be
When run on the emulator, you’ll notice the sample uses animations to re-arrange the user interface when configuration changes are detected.Detecting when the activity is moved from screen to screen
The onConfigurationChanged method will let us know on size changes on our activity, but it will not notify if the user moves the activity from the side to side or top to bottom screens. Detecting that is a little bit more work:- First, find the root view for our activity like this:
View rootView = getWindow().getDecorView().getRootView();
- Add a layout listener using the addOnLayoutChangeListener The listener will fire whenever the user moves the activity.
Keyboard inset
To detect the keyboard inset, you first add android:windowSoftInputMode to your activity manifest:android:windowSoftInputMode="stateAlwaysHidden|adjustResize"(the adjustResize part is the relevant one) Then set a listener with the setOnApplyWindowInsetsListener method on the root view of the activity. Android will call the listener whenever the keyboard appears and the systemWindowInsets.bottom will have the pixel amount taken by the keyboard even if the keyboard is floating.
Figure: keyboard inset 702 pixels
Launching external activity while spanned, without it taking the whole display
Whenever an activity launched another activity within the same Task, the operating system will configure the activity to open on the same configuration of the original one as those activities will occupy the same window. Meaning if our activity is spanned and we will open another, the activity will be spanned as well. This might work well for some scenarios but on others we might want that our activity and the new one will appear side by side. To achieve this, we can use the same mechanism of launching the activity in a new task like we did in the sample and explained in the Bring your app to Surface Duo – Step 2 blog post.intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK| Intent.FLAG_ACTIVITY_NEW_TASK);Use the Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK flags when launching the activity. This will cause the spanned activity to un-span and the current activity to be on the adjacent screen. Try out the Orientation And Spanning sample on GitHub on the Surface Duo emulator, and start applying these ideas to your own Android apps! We look forward to seeing you on the Surface Duo.