How To Update Your Apps For Foldable Displays

How To Update Your Apps For Foldable Displays

Md. Iqbal Hossain

Introduction

Samsung has announced that its foldable device will be available soon. To provide the best experience for this unique device, third-party developers need to make sure their apps are ready to rock, and work seamlessly between two displays.

Apps optimized for foldable devices should seamlessly transition between screens, as well as consider different display attributes such as resolution and density.

Two-or-more apps can run in split-screen (multi-window) mode on the large display (known as the Main Display) of foldable devices. In this mode, developers also need to handle app behavior when focus is changed.

A sample app has been developed to illustrate this transition. In this app a simple UI is designed to keep score of two teams playing a game. To adapt this app for foldable UI, some configurations have been changed by following the official guide.

So how much needs to be changed? Let’s find out.

Getting Started

Setting up the environment

Developers can test their apps on AVD (Android Virtual Device) in Android Studio by installing the emulator provided by Samsung and following this guide on the developer site.

After setting up the environment, a floating button will pop up (illustrated in the image below) to emulate display transition.

Figure 1 – Emulating the foldable phone on emulator

The tablet-like display is called the Main Display and the smaller phone-like display is the Cover Display. To emulate the main and cover displays, you can click between button 1 and button 2 respectively.

App Continuity

App Continuity enables seamless adaptation to different screen sizes. For example, while playing a video on the Cover Display, the user may switch to the Main Display to have a more immersive experience. App Continuity ensures that the user has the same video-playing experience as when they were viewing it on the Cover Display.

This is what happens during the transition: The activity is destroyed and recreated whenever the device is folded or unfolded. To implement this, apps need to restore the previous state before the activity is restarted.

To update your view layout manually during display transition and multi-window, you should add android:configChanges attribute in the manifest as in the following example:

<activity
android:name=".MyActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout"
/>

After making this change to the manifest, you can modify the view layout and restore resources in onConfigurationChanged(), as shown below.

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    // write your code here
}

According to the guide, onSaveInstanceState() and ViewModel object can be used to store and restore previous state.

In this example, ViewModel object is used to store the data and then restore after folding/unfolding.

ViewModel example:

ViewModel was one of the architecture components introduced by the Android team at Google I/O 2017. It has been designed to store and restore UI data. The main objective is to help developers manage configuration changes.

The sample app in this example was developed using ViewModel to avoid data loss during folding and unfolding.

Steps:

  1. Create a class that extends ViewModel to make the distinction between UI controller and data. For each screen, developers have to create a ViewModel class. This class will contain all the data related to its corresponding screen. In this example, members are declared as public. If needed, data can be encapsulated, and developers can use getter and setter methods.
    public class GameViewModel extends ViewModel {
        public int team1Score = 0;
        public int team2Score = 0;
    }
    
  2. Establish an association between ViewModel and UI controller.
    ViewModelProviders.of(<Your UI controller>).get(<Your ViewModel>.class)
    

    In the sample app:

    ViewModelProviders.of(this).get(GameViewModel.class)
  3. Use ViewModel in the app to update data.
    public void increamentForTeam2(View v) {
        viewModel.team2Score = viewModel.team2Score + 1;
        updateTeam2UI(viewModel.team2Score);
    }
    

Multi-Window and Multi-tasking:

The default behavior is for apps to pause when they are out of focus (i.e. onPause() is called). If you wish to enforce multi-resume behavior in multi-window mode, you must add explicit statements to the manifest, as shown below.

<application>
    <meta-data
    android:name="android.allow_multiple_resumed_activities"
    android:value="true" />
    <activity ... />
    </application>

Maximum aspect ratio

Apps that target Android 8.0 (API Level 26) or higher will fill the entire screen. This means that the target SDK version needs to be set at API Level 28. Alternatively, the activity can be declared as resizable, and will fill the entire screen.

If you are using Android 7.1 or lower, you need to add an element named android.max_aspect in the application element.

<!-- Render on full screen up to screen aspect ratio of 2.4
Use a letterbox on screens larger than 2.4 -->
<meta-data android:name="android.max_aspect" android:value="2.4" />

Testing

The source of this sample app is FoldableApp. In this sample app, a simple UI is designed to store the score of two teams playing a game. There is also a text view which shows the current lifecycle state of the app.

During transition between the displays, no data is lost, nor do any UI related issues occur. As the emulator currently does not support multi-resume, the app behavior during out-of-focus can’t be tested. However, it is mentioned in the guide that multi-resume can be tested with Samsung devices running Android 9.0.

Figure 2 – Testing developed app on foldable emulator