Massive Screens & Foldables Tutorial for Android


Massive screens are an essential and fast-growing section of lively Android units. There are greater than 270 million large-screen Android units in use. They embrace tablets, foldable units and Chrome OS units. To achieve this rising section of Android customers, study to make your app UI adaptive throughout a variety of units.

On this tutorial, you’ll construct an app referred to as Artful Pocket book, which exhibits an inventory of notes. Alongside the best way, you’ll find out about:

  • APIs and instruments to construct nice consumer experiences for large-screen Android units.
  • Designing adaptive apps for various display screen sizes, orientations and type components.
  • Google Play updates for large-screen units.
  • Testing your app layouts for big screens.

Getting Began

Obtain the starter undertaking by clicking the Obtain Supplies button on the prime or backside of the tutorial.

On this tutorial, you’ll use a resizable emulator to check your app’s UI throughout totally different units. To arrange a resizable emulator, open the starter undertaking with Android Studio model 2021.2.1 or newer and observe these steps:

  • Click on InstrumentsSDK Supervisor. Within the SDK Instruments tab, choose Android Emulator and click on OK. This can set up the most recent model of the emulator if it isn’t already put in.
  • To create a digital system, click on InstrumentsMachine Supervisor. Then, click on the Create system button and choose CellphoneResizable. Click on Subsequent and choose the most recent API stage. Affirm the emulator particulars and click on End. This can create a resizable emulator.
  • On the checklist of digital units, choose the resizable system and click on the Launch icon to start out it.

Select resizable emulator

Construct and run the undertaking. Right here’s what you’ll see:

List of notes in a compact screen size

Within the emulator window, click on the Show Mode drop-down and choose Pill:

Click device type dropdown to switch to a different device type

On a large-screen system like a pill, content material stretches to fill the out there display screen house like this:

List of notes in a tablet. The UI stretches to fill the available space

However customers anticipate an amazing expertise whereas utilizing your app throughout totally different Android units. Your aim is to make use of the additional display screen house to enhance the consumer expertise and supply nice accessibility on large-screen units.

Trying Into Android 12L Updates

Android units are available varied type components: telephones, tablets, foldables and Chrome OS units. They fluctuate in display screen sizes from small to giant display screen sizes.

At Android Dev summit 2021, Google introduced Android 12L. Android 12L is a characteristic replace for Android 12 that was constructed for large-screen units. Android 13 builds on updates made in Android 12L. Among the updates embrace:

  • Taskbar interplay: The brand new taskbar makes it straightforward to launch and change apps. Gestures resembling drag and drop enter split-screen mode. In gesture navigation, customers can flip via latest apps. This permits highly effective and intuitive multitasking on giant screens.
  • Default multi-window mode: To reinforce the cut up display screen expertise, Android 12 or larger permits multi-window mode by default in all apps.
  • Improved compatibility expertise: Some apps aren’t optimized for big screens but. They aren’t resizable or are utilizing fastened orientation. These apps are launched in compatibility mode to make them look higher by default. Such apps are centered on the display screen with black bars filling the unused show space.
  • Digicam preview enhancements: This makes the digital camera app adaptive to giant screens, multi-window mode and totally different foldable system postures.
  • Media projection updates: Beginning in Android 12L, the digital show is scaled to suit out there display screen house. This improves display screen casting on giant shows like televisions. It maximizes the dimensions of floor photos and ensures the proper facet ratio.

You’ve realized about updates for large-screen units beginning in Android 12L. Subsequent, you’ll discover ways to construct responsive apps throughout totally different units.

Designing Adaptive Apps

Responsive apps present an amazing consumer expertise throughout totally different display screen sizes and type components. They help totally different display screen orientations and resizable configurations like multi-window mode.

That will help you create adaptive layouts, Materials Design 3 offers canonical layouts. Canonical layouts function a tenet for creating responsive layouts for big screens. They embrace:

  • Record-detail view: In a list-detail view, you place an inventory of things on the left. On the precise aspect, you present particulars of an merchandise.
  • Supporting panel: A structure consists of focus and help areas. The main focus area exhibits the first content material. It covers two-thirds of the show space. The supporting panel occupies the remaining display screen house to point out extra content material like feedback on a doc. It’s positioned on the backside third on an expanded peak or trailing third on an expanded width.
  • Feed: Feed layouts are frequent in information or social content material apps. For instance, with a RecyclerView, use a distinct structure supervisor like GridLayoutManager when the width shouldn’t be compact.

Understanding what sort of system the consumer is utilizing received’t aid you determine which app layouts to make use of. On tablets, for instance, an app might be sharing the display screen with one other app in multi-window mode. Or, on a foldable system, there might be multiple bodily display screen. As an alternative, make selections based mostly on the precise portion of the display screen that’s allotted by utilizing Jetpack WindowManager library.

Within the subsequent part, you’ll discover ways to use Window Dimension lessons to find out the structure to your app. Window measurement lessons are decided by the window measurement out there to your software no matter the kind of system the app is working on.

Exploring Window Dimension Lessons

Window measurement lessons are viewport breakpoints to information you in designing responsive and adaptive layouts. They classify display screen house out there to your app as compact, medium or expanded.

Out there width and peak are categorized individually. The out there width is extra essential than the out there peak as a result of vertical scrolling is frequent throughout units. The out there width is classed as follows:

  • Compact width: The system width is lower than 600dp. Telephones in portrait orientation and foldables in folded state are on this class.
  • Medium width: The system width is greater than 600dp. Medium-width units embrace tablets and huge unfolded foldables in portrait orientation.
  • Expanded width: Tablets and huge unfolded foldables in panorama orientation fall on this class. They’re greater than 840dp vast.

You’ll use the material3-window-size-class library to get the window measurement class of a tool. The library calculates the window measurement class utilizing present window metrics.

Open construct.gradle(app). The next library dependency has already been added:

implementation "androidx.compose.material3:material3-window-size-class:1.0.0-alpha14"

Open presentation ▸ MainActivity.kt, and change // TODO 1 with the next:

val windowSizeClass = calculateWindowSizeClass(exercise = this)

The code above returns the window measurement class for the offered exercise. calculateWindowSizeClass(exercise: Exercise) calculates WindowSizeClass for the offered exercise. The tactic returns a brand new WindowSizeClass throughout display screen rotation or window resize. The app recomposes the UI with the brand new window measurement class.

Add any lacking imports by urgent Possibility-Return on Mac or Alt-Enter on PC.

You may even see an error squiggly line. It’s because the library remains to be experimental. To repair the error, add the next earlier than onCreate() and import the corresponding package deal:

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)

Subsequent, you’ll cross windowSizeClass to the NoteApp() composable. You’ll use this data later to find out the app layouts.

Substitute // TODO 2 with the next:

windowSizeClass = windowSizeClass.widthSizeClass,

Earlier than updating the app to reply to adjustments in display screen sizes, you’ll contemplate system fold posture additionally.

Trying Into Machine Fold Posture

A foldable system might be in varied states and postures. It could be folded or unfolded, in portrait or panorama orientation. It might be in a tabletop or e book posture. An adaptive design helps totally different foldable postures.

Jetpack WindowManager library’s WindowLayoutInfo class offers the next details about foldable shows:

  • state: This describes the fold state. Its worth is FLAT when the system is totally opened, or HALF_OPENED.
  • orientation: The orientation of the hinge. It may be HORIZONTAL or VERTICAL.
  • occlusionType: The worth is FULL when the hinge hides a part of the show. In any other case the worth is NONE.
  • isSeparating: It’s true when the hinge creates two logical shows.

You’ll use this data to find out system fold posture. Open presentation ▸ util ▸ DevicePostureUtil.kt. DevicePosture interface defines the next postures:

  • Regular posture: Whether or not a tool is totally opened or totally folded.
  • Guide posture: The system is in portrait orientation and its fold state is HALF_OPENED.
  • Separating posture: The system is totally open and its fold state is FLAT. It’s just like the case of system posture the place occlusionType is FULL due to a bodily hinge. Keep away from putting touchable or seen elements below the hinge.

Analyzing Machine Fold Posture

To get system fold posture, open MainActivity.kt and change // TODO 3 with the next:

// 1
val devicePostureFlow = WindowInfoTracker.getOrCreate(this).windowLayoutInfo(this)
  .flowWithLifecycle(this.lifecycle)
  // 2
  .map { layoutInfo ->
    val foldingFeature =
      layoutInfo.displayFeatures
        .filterIsInstance()
        .firstOrNull()
    when {
      isBookPosture(foldingFeature) ->
        DevicePosture.BookPosture(foldingFeature.bounds)

      isSeparating(foldingFeature) ->
        DevicePosture.Separating(foldingFeature.bounds, foldingFeature.orientation)

      else -> DevicePosture.NormalPosture
    }
  }
  .stateIn(
    scope = lifecycleScope,
    began = SharingStarted.Eagerly,
    initialValue = DevicePosture.NormalPosture
  )

Additionally embrace the next imports to keep away from Android Studio’s complaints:

import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.window.structure.FoldingFeature
import androidx.window.structure.WindowInfoTracker
import com.yourcompany.android.craftynotebook.presentation.util.DevicePosture
import com.yourcompany.android.craftynotebook.presentation.util.isBookPosture
import com.yourcompany.android.craftynotebook.presentation.util.isSeparating
import kotlinx.coroutines.movement.SharingStarted
import kotlinx.coroutines.movement.map
import kotlinx.coroutines.movement.stateIn

Within the code above, you’re utilizing Kotlin Flows to work with WindowLayoutInfo knowledge assortment.

  1. windowLayoutInfo(exercise: Exercise) returns show data of a tool as Circulate. The tactic emits WindowLayoutInfo each time the show data adjustments.
  2. It makes use of map operator and show data returned by windowLayoutInfo(exercise: Exercise) to find out the system fold posture.

Subsequent, you’ll observe system posture as compose state. In MainActivity.kt, change // TODO 4 with the next and import the corresponding package deal.

val devicePosture = devicePostureFlow.collectAsState().worth

Then, cross devicePosture in NoteApp() composable name. Substitute // TODO 5 with the next:

devicePosture = devicePosture,

Up up to now utilizing window measurement lessons, the app is aware of the display screen house out there. It additionally is aware of the system fold posture. You’ll use this data to find out the app UI. First, you’ll implement responsive navigation.

Selecting Applicable Navigation Kind

Responsive UIs embrace various kinds of navigation parts comparable to show measurement adjustments.

Materials library offers navigation elements like backside navigation, navigation rail and navigation drawer. You’ll implement probably the most applicable navigation relying on the window measurement class of a tool:

  • Backside navigation: Backside navigation is most applicable for compact window sizes.
  • Navigation rail: Use navigation rail for medium display screen sizes.
  • Navigation drawer: This might be appropriate for large-screen units like tablets. There are two sorts of navigation drawers: modal and everlasting. Use a modal navigation drawer for compact to medium sizes as a result of it may be expanded as an overlay on the content material or hidden. Use a everlasting navigation drawer for fastened navigation on giant screens like tablets and Chrome OS units.

Now, you’ll change between totally different navigation sorts relying on the window measurement of a category and system fold posture.

Open NoteApp.kt and change // TODO 6 with the next and import the package deal for NavigationType:

// 1
val navigationType: NavigationType
// 2
when (windowSizeClass) {
  WindowWidthSizeClass.Compact -> {
    navigationType = NavigationType.BOTTOM_NAVIGATION
    // TODO 13
  }
  WindowWidthSizeClass.Medium -> {
    navigationType = NavigationType.NAVIGATION_RAIL
    // TODO 14
  }
  WindowWidthSizeClass.Expanded -> {
    // 3
    navigationType = if (devicePosture is DevicePosture.BookPosture) {
      NavigationType.NAVIGATION_RAIL
    } else {
      NavigationType.PERMANENT_NAVIGATION_DRAWER
    }
    // TODO 15
  }
  else -> {
    navigationType = NavigationType.BOTTOM_NAVIGATION
    // TODO 16
  }
}

The code above does the next:

  1. Declares the navigationType variable.
  2. Utilizing a change assertion, it initializes navigationType with the proper worth relying on the window measurement class.
  3. Handles fold state to keep away from putting content material or touching motion on the hinge space. When a tool is in BookPosture, use a navigation rail and divide content material across the hinge. For giant desktops or tablets, use a everlasting navigation drawer.

Subsequent, you’ll cross navigationType to NoteNavigationWrapperUi() composable name. In NoteApp.kt, change // TODO 7 with the next:

navigationType = navigationType,

Now, the app is aware of navigation sorts to use to totally different window measurement lessons and system fold postures. Subsequent, you’ll implement totally different navigation to make sure glorious interplay and reachability.

Implementing Responsive Navigation

Open NoteNavigationWrapperUi.kt. Substitute NoteAppContent() composable name with the next:

if (navigationType == NavigationType.PERMANENT_NAVIGATION_DRAWER) {
  PermanentNavigationDrawer(drawerContent = {
    NavigationDrawerContent(
      navController = navController
    )
  }) {
    NoteAppContent(
      navigationType = navigationType,
      contentType = contentType,
      modifier = modifier,
      navController = navController,
      notesViewModel = notesViewModel
    )
  }
} else {
  ModalNavigationDrawer(
    drawerContent = {
      NavigationDrawerContent(
        navController = navController,
        onDrawerClicked = {
          scope.launch {
            drawerState.shut()
          }
        }
      )
    },
    drawerState = drawerState
  ) {
    NoteAppContent(
      navigationType = navigationType,
      contentType = contentType,
      modifier = modifier,
      navController = navController,
      notesViewModel = notesViewModel,
      onDrawerClicked = {
        scope.launch {
          drawerState.open()
        }
      }
    )
  }
}

As standard, there are a number of imports it’s good to add as properly:

import kotlinx.coroutines.launch
import androidx.compose.material3.*

The navigation drawer is the container for notes UI. Within the code above, you’re wrapping the NoteAppContent() composable name with a everlasting or modal navigation drawer relying on the worth of navigationType.

In NoteAppContent.kt, change the Column() composable with the next:

Row(modifier = Modifier.fillMaxSize()) {
  AnimatedVisibility(seen = navigationType == NavigationType.NAVIGATION_RAIL) {
    NoteNavigationRail(
      onDrawerClicked = onDrawerClicked,
      navController = navController
    )
  }
  Column(
    modifier = modifier.fillMaxSize()
  ) {
    NoteNavHost(
      modifier = modifier.weight(1f),
      contentType = contentType,
      navController = navController,
      notesViewModel = notesViewModel
    )
    AnimatedVisibility(seen = navigationType == NavigationType.BOTTOM_NAVIGATION) {
      NoteBottomNavigationBar(navController = navController)
    }
  }
}

To make Android Studio completely satisfied, add the next imports as properly:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.basis.structure.Row

The code above makes use of navigationType to find out placement of navigation rail or backside navigation. You wrapped each navigation rail and backside navigation within the AnimatedVisibility() composable. This animates the entry and exit visibility of every navigation relying on navigationType .

Construct and run.

For compact window measurement class like a telephone, the app makes use of backside navigation like within the display screen beneath:

A compact screen window size class like a phone uses bottom navigation

In a medium window measurement class, the app makes use of a navigation rail like within the display screen beneath:

A medium window size class like unfolded foldable uses navigation rail

The app makes use of a everlasting navigation drawer in an expanded window measurement class, like this:

A large screen using a permanent navigation drawer

Congratulations! You’ve efficiently carried out dynamic navigation on totally different units. Subsequent, you’ll make the most of the extra display screen house to point out extra content material. You’ll implement list-detail on giant screens.

Displaying Extra Content material

Open presentation ▸ util ▸ ConstantsUtil.kt. ContentType enum defines two constants: LIST_ONLY and LIST_AND_DETAIL. These will aid you decide content material structure relying on the window measurement class.

Open NoteApp.kt. Substitute // TODO 12 with the next and import the corresponding package deal:

val contentType: ContentType

Right here, you’ve declared a variable of kind ContentType.

Subsequent, you’ll initialize the contentType variable with the proper worth relying on display screen state.

In NoteApp.kt, change the TODOs within the when assertion as proven beneath:

Substitute // TODO 13 with the next code:

contentType = ContentType.LIST_ONLY

It units the worth of contentType with as LIST_ONLY when the window measurement class is compact.

Substitute // TODO 14 with the next 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 measurement class. For a foldable system in e book posture, set the worth to LIST_DETAIL. This can separate checklist view and element view on the hinge space. It helps keep away from putting content material or contact targets on the hinge space.

Substitute // TODO 15 with the code beneath:

contentType = ContentType.LIST_AND_DETAIL

This units the worth of contentType as LIST_AND_DETAIL on giant screens.

Lastly, change // TODO 16 with the code beneath to incorporate the default case:

contentType = ContentType.LIST_ONLY

Subsequent, cross contentType to the NoteNavigationWrapperUi() composable. Substitute // TODO 17 with the next:

contentType = contentType,

You’ll use the contentType parameter to find out whether or not to point out an inventory structure or a list-detail structure.

Open NotesScreen.kt. Substitute the NotesListComposable() composable name with the next:

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

The code above checks the worth of contentType to find out which structure to point out. The app will present a list-detail structure on giant screens. In compact and medium display screen sizes, the app will present an inventory structure.

Construct and run.

On a compact or medium display screen measurement, the app exhibits an inventory structure like within the screens beneath:

A compact screen size shows a list layout

A medium screen size shows a list layout

On giant screens like a pill or desktop, the app exhibits a list-detail structure like this:

An expanded window size class showing a list-detail view

Guaranteeing Information is Out there for All Display Sizes

A responsive UI retains knowledge when a telephone is rotated or a foldable is unfolded or folded. Altering telephone orientation, folding and unfolding a foldable or resizing a window are configuration adjustments. Throughout configuration adjustments, the system recreates app actions, fragments or composables. The advisable methods to protect knowledge throughout configuration adjustments are utilizing a ViewModel class and rememberSavable API for compose apps.

On giant screens, you could be exhibiting extra content material to make the most of the additional display screen house. So, you could be tempted to fetch knowledge when the display screen measurement adjustments. This goes towards the precept of unidirectional knowledge movement — that state flows down and occasions movement up — the place knowledge must be hoisted and offered to the composables for displaying.

It is best to present sufficient knowledge to the composable in order that it at all times has what it must show throughout any display screen measurement. Then, you need to use a flag like contentType to find out what knowledge to point out on a given display screen measurement.

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

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

An inventory of notes is handed to each NotesListComposable() and NoteListDetailComposable() composables. Full notice textual content is not going to be displayed on a small or medium display screen measurement. Nonetheless, it’ll be out there for displaying on giant screens that present each the checklist of notes and particulars of a notice merchandise.

You’ve realized methods to construct adaptive apps whereas guaranteeing knowledge is obtainable throughout totally different system configurations. Subsequent, you’ll discover ways to check your app compatibility throughout totally different display screen sizes and type components.

Testing Apps for Massive Screens With Android Studio

To check your app compatibility with large-screen units, Android Studio offers the next capabilities:

  • Reference units: These embrace telephones, giant foldable inside show, tablets and desktops. You may create device-respective emulators in Android Studio. Then, you’ll use the emulators to check your app structure throughout totally different units.
  • Resizable emulator: Resizeable emulator is obtainable in Android Studio chipmunk and better. It permits you to toggle between the 4 reference units — telephone, foldable, pill and desktop — to validate your app structure at runtime.
  • Format validation: Beginning Electrical Eel Canary 1, Android Studio will examine for visible lint points throughout totally different display screen sizes. Once you open Format Validation, you’ll see all of your layouts render in a number of system sizes. If there’s a problem, it’ll present up within the Issues Panel. Visible linting might be out there for layouts written in Views or Compose.

Now, you’ll look into what to check to make sure your app compatibility in several display screen sizes and type components.

Trying Into What to Check in Massive Screens

When you’ve arrange totally different system emulators, you’ll check your app for frequent use circumstances for big screens. Among the issues to check for embrace:

  • Display sizes, system posture and orientation: Examine how your app responds to adjustments in display screen sizes, system posture of a foldable and display screen orientation.
  • Taskbar integration and cut up display screen mode: For Android 12L units and better, guarantee your app UI isn’t blocked by the taskbar. Examine your app conduct whenever you enter multi-window mode utilizing the taskbar. Check switching between your app and different apps utilizing the taskbar.
  • Multi-window mode: Examine your app conduct when working in multi-window mode on giant screens when android:resizeableActivity = false in AndroidManifest file. If android:resizeableActivity = true, examine how your app responds when working in multi-window mode on small-screen units.
  • Media projection: In case your app makes use of media projection, examine how your app responds whereas taking part in again, streaming or casting media on large-screen units. Additionally examine how the app responds to system posture adjustments in a foldable.
  • Digicam preview: For digital camera apps, examine how the digital camera preview UI responds on giant screens when your app is in multi-window mode. Examine how your app responds to system posture adjustments on a foldable system.

Checking Into Google Play Updates for Massive Screens

The Android staff has up to date Google Play to spotlight apps which are optimized for big screens. They’ve added checks to evaluate apps towards the big screens app high quality pointers listed right here. If an app isn’t optimized for big screens, customers on large-screen units might be notified on the app’s Play Retailer itemizing web page.

They’ve additionally launched large-screen-specific app rankings. Customers can fee how your app works on their large-screen system.

Optimize your Android apps to make them straightforward to search out on Google Play!

The place to Go From Right here?

Obtain the finished undertaking recordsdata by clicking the Obtain Supplies button on the prime or backside of the tutorial.

Congratulations! You have got efficiently made the Artful Pocket book App responsive throughout totally different units. You have got realized methods to make your app adaptive to totally different display screen sizes and type components utilizing Jetpack Compose. You’ve additionally realized methods to protect state throughout configuration adjustments and Google Play updates for large-screen units.

Massive screens are good for drag-and-drop interactions — inside the app or between apps in multi-window mode. Take a look at Android Drag and Drop to discover ways to add drag-and-drop capabilities to your app.

Take a look at this Guaranteeing Nice Enter Help for All Units discuss to find out about supporting varied enter strategies in all units.

We hope you loved this tutorial. When you have any questions or feedback, please be a part of the discussion board dialogue beneath!

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles