Foldable Device Posture and Hinge-Aware Compose Layouts

Quick answer: Start with a layout that works in any rectangular window. Then use currentWindowAdaptiveInfoV2().windowPosture when a reported fold or hinge changes what people can see or reach. Keep important content out of an occluding or separating hinge, use tabletop posture to divide content above and controls below when that improves the task, and preserve the user’s state when the device folds, unfolds, rotates, or resizes.

Foldables are not merely large phones. The same app can move between a compact cover display, a broad inner display, split-screen, a half-open tabletop posture, and a book-like vertical fold. The reliable design input is the current app window plus relevant folding features—not a manufacturer name, a device model, or a fixed orientation.

The Android foldables overview recommends responsive design as the baseline, then adaptive layouts when the folded and unfolded shapes need materially different arrangements. That gives every device a usable experience while letting a fold genuinely improve a task where appropriate.

Know what a folding feature tells you

A fold can be flexible display area or a physical hinge that separates displays. Jetpack WindowManager represents it as a FoldingFeature; Material 3 Adaptive exposes the relevant information as Posture and HingeInfo in WindowAdaptiveInfo.

SignalMeaning for a layout
Horizontal hingeIt divides the window into upper and lower regions. A half-opened horizontal hinge can be tabletop posture.
Vertical hingeIt divides the window into left and right regions. It may support book-like reading or an intentionally separated layout.
isSeparatingTreat the fold as a boundary between logical regions; controls near it can be hard to reach.
isOccludingNo content is visible in the hinge area. Never draw or place an essential target there.
isFlatThe relevant window space is fully open and flat.

The distinction between separating and occluding matters. An occluding hinge is also separating, but a separating fold is not necessarily hidden display space. In both cases, do not run text, controls, dialogs, or a continuous media subject through the boundary without a deliberate design reason.

Android does not expose a precise hinge angle as a dependable general-purpose input. Devices have different reporting ranges and sensor accuracy, so use the reported state, orientation, bounds, and separation properties rather than trying to animate or branch at a specific angle.

Get posture from Material 3 Adaptive

In Material 3 Adaptive 1.3.0+, currentWindowAdaptiveInfoV2() returns both the current window size class and windowPosture. It replaces the deprecated currentWindowAdaptiveInfo() API and updates as the relevant window information changes.

dependencies {
    implementation("androidx.compose.material3.adaptive:adaptive:1.3.0")
}

Use the version managed by your project and check the Material 3 Adaptive release notes before upgrading. The adaptive Posture API gives a Compose screen a clear, testable input without each destination setting up its own WindowInfoTracker collection.

import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2
import androidx.compose.material3.adaptive.separatingVerticalHingeBounds
import androidx.compose.runtime.Composable

@Composable
fun ReaderDestination() {
    val posture = currentWindowAdaptiveInfoV2().windowPosture

    when {
        posture.isTabletop -> {
            TabletopReader(
                // Keep reading content above the horizontal hinge and controls below it.
            )
        }

        posture.separatingVerticalHingeBounds.isNotEmpty() -> {
            VerticalHingeReader(
                // Use two independent regions only when it benefits reading or comparison.
            )
        }

        else -> StandardReader()
    }
}

isTabletop is true when the window has a half-opened horizontal hinge in the middle. separatingVerticalHingeBounds identifies vertical hinge bounds that create two logical regions. The Posture API reference also provides horizontal, vertical, separating, and occluding hinge-bound lists for more specialized policies.

The code intentionally chooses layout policy, not pixel placement. Hinge bounds are in window coordinates, not necessarily the local coordinates of a deeply nested composable. Keep the decision at the screen boundary, then let the chosen top-level layout own its measurement and placement.

Use posture only when it helps the task

An extra branch costs focus, Back behavior, state continuity, and testing. Make it earn that cost.

Tabletop: separate presentation from interaction

A tabletop posture has a horizontal hinge. It can work well when the user benefits from hands-free viewing or a clear division of roles:

  • Video, a camera preview, or a presentation above the hinge; playback or capture controls below it.
  • A call or shared content above; chat, reactions, or device controls below it.
  • A reading preview above; page controls or annotations below it.

Keep the default full-window experience when the posture does not make the task better. A normal feed, settings form, or article should not become a divided layout merely because the device can fold.

Vertical hinge: treat it as a real boundary

A vertical separating hinge can create a book-like arrangement. It can help with comparing two related documents, retaining a list beside a selected item, or putting a stable tool region alongside primary content. Build a List-Detail Layout with Compose Adaptive APIs shows the Navigation 3 strategy for a genuine list-to-detail relationship.

Do not split a single paragraph, a large image subject, a slider, or a primary action across the fold. If the hinge is occluding, that content will be invisible. Even when it is not occluding, a target pressed against the fold can be awkward to reach.

Let adaptive scaffolds avoid hinges when they own the panes

When a Material 3 Adaptive pane layout owns the screen’s structure, prefer its hinge-aware layout policy over recreating pane geometry by hand. HingePolicy offers choices including AvoidOccluding, AvoidSeparating, and AlwaysAvoid; select the smallest policy that protects the task.

  • Use AvoidOccluding when only a hidden physical gap is unacceptable.
  • Use AvoidSeparating when interaction near any logical boundary would be uncomfortable or confusing.
  • Use AlwaysAvoid only when all reported hinges should be protected, including flat or non-separating cases.

The HingePolicy reference documents these choices. Do not add arbitrary spacer widths copied from one device. The actual bounds and whether they matter can change with the device, posture, app window, and multi-window placement.

For custom layouts, use the same principle: divide the available content area around the real hinge when it is relevant. Never assume that the midpoint of the device, the midpoint of the app window, or portrait orientation is the fold location.

Keep a rectangular fallback first

Not every foldable reports a relevant feature to every app window, and most users do not own a foldable. Your normal layout must therefore remain the source of truth.

  1. Build a responsive single-window screen that supports compact and wide sizes.
  2. Use window size classes for high-level choices such as navigation or useful simultaneous content.
  3. Add posture-specific behavior only for a meaningful reported hinge and a task that benefits from it.
  4. Fall back cleanly when there is no hinge, the window is too small, or the app is in split-screen.

This ordering prevents a common mistake: a phone, tablet, ChromeOS window, or a foldable’s cover display is accidentally treated as an unsupported special case. The broader adaptive layouts guide covers this window-first design model.

Preserve continuity through fold and unfold

Folding or unfolding can change window size, posture, orientation, and sometimes the activity configuration. It must not erase the user’s work.

  • Store durable screen data and business state in a ViewModel or another appropriate state holder.
  • Use rememberSaveable for small restorable UI state such as a query, selected filter, expanded section, or draft identifier.
  • Represent selection by a stable ID or navigation key, not by “the item in the left region.”
  • Hoist scroll state when a parent needs to coordinate the transition; do not reset a reading position because the content moved above a hinge.
  • Recompute posture policy from the current adaptive information. Do not persist isTabletop or isFoldable as a user setting.

The Android foldables guidance emphasizes state restoration as the device transitions between screens. Treat a posture change as a new arrangement of the same user session, not as a reason to start the destination again.

Insets, dialogs, and accessibility still apply

A hinge is an additional layout constraint; it does not replace system-bar, cutout, gesture, or IME handling. Assign every protected region a clear owner. A bottom control area in tabletop mode must still stay clear of the keyboard and navigation area, and a dialog must not straddle an occluding or separating fold.

Edge-to-Edge UI in Jetpack Compose explains the complementary inset discipline. Test focus order too: an upper and lower region, or left and right regions, can make a formerly linear keyboard and screen-reader path ambiguous. Ensure that all actions remain reachable and that the focus order follows the visual and task order.

Test posture transitions, not only screenshots

Test the same task in ordinary, folded, flat, tabletop, and vertical-hinge situations where your product supports them.

  1. Begin on a compact or normal window, select content, type a draft, scroll, or start media playback.
  2. Fold, unfold, rotate, resize, or enter split-screen while the state is active.
  3. Verify that no essential text, control, dialog, or menu intersects the hinge; check both separating and occluding cases when available.
  4. Confirm selection, drafts, media state, scroll intent, Back behavior, and focus remain understandable.
  5. Repeat with large font scaling, visible system bars, IME open, and keyboard or pointer input where applicable.

Use previews and screenshot tests to make the intended regions visible, then confirm on supported emulators or physical hardware. A static fully open tablet-like preview cannot prove that a half-opened hinge and its transition preserve the task.

Common mistakes

Using orientation as a hinge detector

Landscape does not imply a horizontal hinge, and portrait does not imply a vertical one. Natural device orientation also differs across foldables. Use reported folding features and window posture.

Drawing through a physical gap

An occluding hinge makes content invisible. A separating hinge can still make text and touch targets difficult to use. Place content in regions, not across an assumed continuous canvas.

Copying one device’s geometry

Do not hard-code a center divider or a fixed hinge width. Bounds can vary by hardware and by the portion of the display allocated to the app.

Losing state during a posture change

The visual branch may change, but selection, drafts, navigation, and user progress should persist. State holders and stable keys are more reliable than view-specific mutable flags.

FAQ

Do I need a custom layout for every foldable?

No. A good responsive baseline covers most cases. Add hinge-aware behavior when a reported posture or boundary improves the actual task or protects essential content.

Is tabletop posture the same as landscape?

No. Tabletop posture is a half-opened horizontal hinge configuration. A landscape rectangle can exist without a fold, and a foldable can change posture without the app receiving the orientation you expected.

Should I always avoid a separating hinge?

Usually avoid placing continuous reading content and controls over it. Whether the whole layout should avoid it depends on the task. A deliberate two-region presentation can use the boundary as a separator while still keeping interactive content away from the fold itself.