March 26th, 2020

Introducing dual-screen layouts for Android

Craig Dunn
Principal SW Engineer

Hello Android dual-screen developers!

Today we are releasing a preview of our first dual-screen layout control for Java and Kotlin developers. The new control and associated helpers will enable you to build dynamic and responsive apps that take advantage of the Microsoft Surface Duo and its two screens.

New SDK features

Today’s release includes three elements that build upon the display mask and other APIs:

  • SurfaceDuoLayout – a control that helps manage single-screen and dual-screen layouts in a flexible way.
  • SurfaceDuoScreenManager – used to subscribe to screen mode changes and have your app respond accordingly.
  • ScreenHelper – provides information about the screen and hinge to help you position elements in your UI.

This post explains one of many ways to take advantage of these new features, you can learn more in the SurfaceDuoLayout documentation.

Add to your project

To try out these features, first update your Android Studio project:

  1. In the top-level build.gradle file, add these lines inside the allprojects { repositories { section:
    maven {
        url 'https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1'
    }
    
  2. In your module-level build.gradle file, add this line in the dependencies { section:
    implementation 'com.microsoft.device:dualscreen-layout:0.9.0'
  3. Java projects should also add this line to their build.gradle dependencies, because the library is built with Kotlin:
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  4. Initialize a SurfaceDuoScreenManager instance in your Application class so you can react to access device statues in your code:
    SurfaceDuoScreenManager surfaceDuoScreenManager;
    
    @Override
    public void onCreate() {
        super.onCreate();
        surfaceDuoScreenManager = SurfaceDuoScreenManager.init(this);
    }
    
    public SurfaceDuoScreenManager getSurfaceDuoScreenManager() {
        return surfaceDuoScreenManager;
    }

    getSurfaceDuroScreenManager will be used in your activities to configure listeners for device mode changes.

Using SurfaceDuoLayout

You can implement dual-screen behavior both using layouts or by listening for screen change events and manipulating fragments, or a combination of the two approaches.

It’s possible to create a sophisticated, responsive UI declaratively, as shown in the CompanionPaneLevel2 sample (Java, Kotlin). In the sample, the main activity contains the following XML layout:

It uses the SurfaceDuoLayout and sets three attributes to define the single- and dual-screen behavior:

  • single_screen_layout_id – layout to load in single screen mode, or on other devices.
  • dual_screen_start_layout_id – layout for the left-side screen.
  • dual_screen_end_layout_id – layout for the right-side screen.

Each of those layouts can be further specialized (if required) with landscape and portrait versions, as shown in this screenshot:

Layout XML file tree

Figure 1: Layout resource definitions

You create/edit these layouts as you normally would in Android Studio:

Android Studio layout design surface

Figure 2: Android Studio layout editor

Here are some screenshots of the CompanionPaneLevel2 sample app in different modes:

Portrait and landscape device screenshots

Figure 3: Single-screen and dual-screen layouts using SurfaceDuoLayout

SurfaceDuoScreenManager

To use the SurfaceDuoScreenManager, add a listener in your application or activity where you can react to screen state changes, as shown in this code snippet:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ((CompanionPaneApp) getApplication()).getSurfaceDuoScreenManager()
        .addScreenModeListener(new ScreenModeListener() {

            @Override
            public void onSwitchToSingleScreenMode() {
               // TODO: Add single-screen behavior
            }

            @Override
            public void onSwitchToDualScreenMode() {
                // TODO: Add dual-screen behavior
            }

        });
}

You might add code to update views in the activity (like the CompanionPane sample for Java & Kotlin), or use fragment manager to adjust the UI (like the MasterDetail sample for Java & Kotlin).

ScreenHelper

The ScreenHelper provides information about the device, to help your code understand the device state. There are four static functions:

  • getHinge – returns the co-ordinates of the seam where the device’s hinge fits between the two displays.
  • getScreenRectangles – when the device is spanned, returns two rectangles representing the dimensions of the screens.
  • isDualMode – whether the application is spanned or not.
  • getCurrentRotation – returns the device rotation (0, 90, 180, or 270 degrees).

These functions can be used in conjunction with the ScreenManager to reason about the device state and render the appropriate UI.

Resources and feedback

Refer to the SurfaceDuoLayout documentation for more detailed explanations of the alternative approaches for using the SurfaceDuoLayout control. Cross-platform developers using Xamarin should refer to the previous post on bringing Xamarin apps to Surface Duo.

We would love to hear from you about your experiences using the SDK, emulator, and your thoughts on how you can utilize these in your apps.

Please reach out using our feedback forum or message me on Twitter or GitHub.

Author

Craig Dunn
Principal SW Engineer

Craig works on the Surface Duo Developer Experience team, where he enjoys writing cross-platform code for Android using a variety of tools including the web, React Native, Flutter, Unity, and Xamarin.

4 comments

Discussion is closed. Login to edit/delete existing comments.

  • Trevor Jones

    “Java projects should also add this line to their build.gradle dependencies, because the library is built with Kotlin”

    If the package is published with a proper pom file, the build system will handle that automatically.

    • Craig DunnMicrosoft employee Author

      Thanks for the feedback – will revisit our config and see what we can do better.

  • Jason Rai

    Is the SDK open source? Can’t see a link to the code.

    • Craig DunnMicrosoft employee Author

      Source code will be coming soon – we’ll post about it here on the blog when it’s available. Thanks for asking!