Large Screens & Foldables Tutorial for Android

Learn how to build great user experiences for large screens & foldables in Android. Also learn how to design and test adaptive Android apps. By Beatrice Kinya.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Displaying More Content

Open presentation ▸ util ▸ ConstantsUtil.kt. ContentType enum defines two constants: LIST_ONLY and LIST_AND_DETAIL. These will help you determine content layout depending on the window size class.

Open NoteApp.kt. Replace // TODO 12 with the following and import the corresponding package:

val contentType: ContentType

Here, you’ve declared a variable of type ContentType.

Next, you’ll initialize the contentType variable with the correct value depending on screen state.

In NoteApp.kt, replace the TODOs in the when statement as shown below:

Replace // TODO 13 with the following code:

contentType = ContentType.LIST_ONLY

It sets the value of contentType with as LIST_ONLY when the window size class is compact.

Replace // TODO 14 with the following code:

contentType = if (devicePosture is DevicePosture.BookPosture
  || devicePosture is DevicePosture.Separating
) {
  ContentType.LIST_AND_DETAIL
} else {
  ContentType.LIST_ONLY
}

The code above initializes contentType with LIST_ONLY for medium window size class. For a foldable device in book posture, set the value to LIST_DETAIL. This will separate list view and detail view at the hinge area. It helps avoid placing content or touch targets at the hinge area.

Replace // TODO 15 with the code below:

contentType = ContentType.LIST_AND_DETAIL

This sets the value of contentType as LIST_AND_DETAIL on large screens.

Finally, replace // TODO 16 with the code below to include the default case:

contentType = ContentType.LIST_ONLY

Next, pass contentType to the NoteNavigationWrapperUi() composable. Replace // TODO 17 with the following:

contentType = contentType,

You’ll use the contentType parameter to determine whether to show a list layout or a list-detail layout.

Open NotesScreen.kt. Replace the NotesListComposable() composable call with the following:

if (contentType == ContentType.LIST_AND_DETAIL) {
  NoteListDetailComposable(notes = notes)
} else {
  NotesListComposable(
    notes = notes,
    onItemSelected = onNoteItemSelected,
  )
}

The code above checks the value of contentType to determine which layout to show. The app will show a list-detail layout on large screens. In compact and medium screen sizes, the app will show a list layout.

Build and run.

On a compact or medium screen size, the app shows a list layout like in the screens below:

A compact screen size shows a list layout

A medium screen size shows a list layout

On large screens like a tablet or desktop, the app shows a list-detail layout like this:

An expanded window size class showing a list-detail view

Ensuring Data is Available for All Screen Sizes

A responsive UI retains data when a phone is rotated or a foldable is unfolded or folded. Changing phone orientation, folding and unfolding a foldable or resizing a window are configuration changes. During configuration changes, the system recreates app activities, fragments or composables. The recommended ways to preserve data across configuration changes are using a ViewModel class and rememberSavable API for compose apps.

Note: To learn more about state in Jetpack Compose, check out State and Jetpack Compose. Check out the Surviving Configuration Changes in Android tutorial to learn more about handling configuration changes.

On large screens, you may be showing more content to utilize the extra screen space. So, you may be tempted to fetch data when the screen size changes. This goes against the principle of unidirectional data flow — that state flows down and events flow up — where data should be hoisted and provided to the composables for displaying.

You should provide enough data to the composable so that it always has what it needs to display across any screen size. Then, you can use a flag like contentType to determine what data to show on a given screen size.

Open NotesScreen.kt. You’ll see code like this:

val notes = notesViewModel.notes.collectAsState().value
if (contentType == ContentType.LIST_AND_DETAIL) {
  NoteListDetailComposable(notes = notes)
} else {
  NotesListComposable(
    notes = notes,
    onItemSelected = onNoteItemSelected,
  )
}

A list of notes is passed to both NotesListComposable() and NoteListDetailComposable() composables. Full note text will not be displayed on a small or medium screen size. However, it’ll be available for displaying on large screens that show both the list of notes and details of a note item.

You’ve learned how to build adaptive apps while ensuring data is available across different device configurations. Next, you’ll learn how to test your app compatibility across different screen sizes and form factors.

Testing Apps for Large Screens With Android Studio

To test your app compatibility with large-screen devices, Android Studio provides the following capabilities:

  • Reference devices: These include phones, large foldable inner display, tablets and desktops. You can create device-respective emulators in Android Studio. Then, you’ll use the emulators to test your app layout across different devices.
  • Resizable emulator: Resizeable emulator is available in Android Studio chipmunk and higher. It lets you toggle between the four reference devices — phone, foldable, tablet and desktop — to validate your app layout at runtime.
  • Layout validation: Starting Electric Eel Canary 1, Android Studio will check for visual lint issues across different screen sizes. When you open Layout Validation, you’ll see all your layouts render in multiple device sizes. If there’s an issue, it’ll show up in the Problems Panel. Visual linting will be available for layouts written in Views or Compose.

Now, you’ll look into what to test to ensure your app compatibility in different screen sizes and form factors.

Looking Into What to Test in Large Screens

Once you’ve set up different device emulators, you’ll test your app for common use cases for large screens. Some of the things to test for include:

  • Screen sizes, device posture and orientation: Check how your app responds to changes in screen sizes, device posture of a foldable and screen orientation.
  • Taskbar integration and split screen mode: For Android 12L devices and higher, ensure your app UI isn’t blocked by the taskbar. Check your app behavior when you enter multi-window mode using the taskbar. Test switching between your app and other apps using the taskbar.
  • Multi-window mode: Check your app behavior when running in multi-window mode on large screens when android:resizeableActivity = false in AndroidManifest file. If android:resizeableActivity = true, check how your app responds when running in multi-window mode on small-screen devices.
  • Media projection: If your app uses media projection, check how your app responds while playing back, streaming or casting media on large-screen devices. Also check how the app responds to device posture changes in a foldable.
  • Camera preview: For camera apps, check how the camera preview UI responds on large screens when your app is in multi-window mode. Check how your app responds to device posture changes on a foldable device.