A screen can look correct at launch and still hide its last field when the keyboard opens or its save button after rotation.
Android edge to edge testing verifies that backgrounds can extend behind system UI while important content remains visible and usable. A transparent status bar is only one checkpoint. Navigation controls, display cutouts, the software keyboard, and separate windows can each expose a different layout defect.
This guide uses a fictional FieldNote app with a long editing form, a photo viewer, and a confirmation dialog. All scenarios are proposed synthetic tests, not reported hands-on results. Use them alongside your Android beta testing plan to give testers a precise assignment.
Follow a repeatable edge-to-edge testing workflow

Start with one screen and an explicit layout contract. The photo background may reach the window edges, while the title, close control, form fields, and save action must remain clear of relevant obstructions.
- Record the installed build, target SDK, device OS, navigation mode, orientation, and window size.
- Identify which component owns each inset and which surfaces deliberately draw behind system UI.
- Capture the initial screen, then open the keyboard, scroll, rotate, and dismiss it.
- Tap the boundary controls and exercise dialogs and fullscreen transitions.
- Compare expected and actual geometry, attach evidence, and repeat the same case after the fix.
Keep the fixture small enough to reproduce without a network dependency. Seed a long note with synthetic text and put a required field near the bottom. A short form can pass while never exercising the region where the keyboard hides content.
Build an OS and target SDK matrix
Separate enforcement from explicit opt-in
Android 15 behavior changes establish default edge-to-edge enforcement for apps targeting API 35 on Android 15. Raising compile SDK alone does not describe the installed app's target behavior. Inspect the artifact and activity theme, including any opt-out, rather than trusting a developer's local configuration.
To enable edge-to-edge explicitly in an Android app on earlier OS versions, use WindowCompat.enableEdgeToEdge(window) in the activity's onCreate, after super.onCreate(savedInstanceState) and before installing content. The WindowCompat reference lists this API as added in AndroidX Core 1.17.0. Existing ComponentActivity code may use the androidx.activity.enableEdgeToEdge extension, introduced in Activity 1.8.0; its API reference marks it deprecated in 1.14.0-alpha03 in favor of WindowCompat. Check resolved dependency versions before choosing the call. Enabling the window does not apply content padding, so continue with the inset checks below.
Use separate rows for Android 14 with explicit edge-to-edge enabled, Android 15 with targets 34, 35, and 36, and Android 16 with targets 35 and 36. For migration comparisons, keep the same screen implementation and record whether an opt-out or explicit setup is present. The target 34 row provides a legacy control, not a prediction of the release build.
Verify the Android 16 opt-out boundary
The Android 16 target behavior documentation makes an important distinction. With target 36, windowOptOutEdgeToEdgeEnforcement still works on Android 15, but is disabled on Android 16. A target 36 build passing on Android 15 with that attribute enabled can conceal a migration failure.
Include target 35 on Android 16 as a comparison where the temporary opt-out remains relevant. Test the candidate without the opt-out on both OS versions. Label compatibility overrides as diagnostic experiments and verify the final artifact under ordinary platform behavior.
Cross the highest-risk rows with gesture and three-button navigation. Add supported older devices when your compatibility code handles insets differently. Coverage means recorded combinations, not an unqualified statement that Android 16 passed.
Check status bars and navigation bars independently
Verify backgrounds and icon contrast
Under Android 15 enforcement, the status bar and gesture navigation bar are transparent, while three-button navigation has a contrast background by default. Legacy status bar color setters no longer provide the same control. Consult the system bar changes before treating a changed color as a padding failure.
Test light and dark themes with a pale photo, a dark photo, and a scrolling list. Expect status icons to remain readable as content changes behind them. Check the top toolbar's actual bounds separately from the background that intentionally extends upward.
Exercise gesture and three-button boundaries
In gesture navigation, test the bottom save action, a draggable sheet, and a horizontal carousel near the side edge. In three-button navigation, repeat the save action with the larger system control area. A screenshot can show a visible button even when the system intercepts the intended interaction.
Android's inset type reference distinguishes drawing boundaries from gesture boundaries. Use safeDrawing for obscured content and consider safeGestures or safeContent for controls with competing gestures. Never substitute one fixed bottom padding value for all navigation modes.
Treat contrast enforcement changes as design decisions. Removing a three-button scrim requires checking readability against every relevant background. It does not remove the need to position controls away from the system navigation area.
Test display cutouts and landscape layouts
For non-floating windows targeting 35 on Android 15, cutout modes such as NEVER and SHORT_EDGES are interpreted as ALWAYS. The display cutout guide explains why an old theme setting cannot reliably reserve that region.
Use a cutout emulator configuration to expose layout assumptions, then repeat on a physical device with a cutout. Rotate in both landscape directions. Expect text and close controls to avoid the cutout even when the background spans the entire display. Side insets matter when the obstruction moves away from the portrait top edge.
Test the long form in landscape with the keyboard visible. Scroll to the last field and save without dismissing the keyboard unless that is the intended product flow. Preserve entered text across rotation so a reset form does not accidentally hide the layout defect.
Also resize a supported tablet or foldable window. Measure the current window rather than deriving space from the full display. Record unsupported configurations explicitly instead of presenting a portrait phone capture as universal coverage.
Trace inset ownership in Compose and Views
Audit Compose padding and consumption
Material 3 Scaffold supplies innerPadding, but your content must apply it. The Material 3 inset guide demonstrates using it as list contentPadding with consumeWindowInsets(innerPadding). Inspect the installed Material version and components before assuming an app bar already handles its edge.
Find duplicate padding in nested containers
Trace the outer scaffold, the screen root, and the list. A manually padded wrapper plus raw inset values inside a child can reserve the same region twice. Annotate which layer owns the top, bottom, and side boundaries before changing modifiers.
Compose inset padding modifiers cooperate through consumption, as described in inset setup. Raw asPaddingValues() does not follow that consumption accounting. Do not assume every nested padding call will automatically deduplicate. Compare the first row's position and the final row's scroll range with the intended layout.
Audit View listeners and mixed screens
For Views, inspect ViewCompat.setOnApplyWindowInsetsListener and the types requested through WindowInsetsCompat. The Views edge-to-edge guide covers system bar and cutout handling. Preserve original design padding and calculate each update from that baseline.
Catch accumulated padding after redispatch
Reopen the keyboard several times, rotate, and return from another activity. If a listener adds insets to the view's current padding, repeated dispatch can grow the gap. Expect identical final geometry after each equivalent transition. Fix the calculation rather than hiding the extra space with a negative margin.
On Android 10 and earlier, consuming insets can prevent sibling delivery. Check the documented ViewGroupCompat.installCompatInsetsDispatch approach against your AndroidX version before consuming them. Keep compatibility coverage if those OS versions remain supported.
In hybrid screens, specify whether the View parent or Compose child owns the boundary. The Views and Compose interoperability guide describes this choice. Test a Compose form inside an existing View activity separately from a fully Compose screen.
Verify IME transitions and long forms
Keep the focused field and action reachable
The input method editor, or IME, introduces a changing obstruction. Test focus on the first, middle, and last fields. Expect the focused field to be visible, the remaining fields reachable by scrolling, and the save action available according to the screen's documented behavior.
For Compose, examine imePadding() and the surrounding consumption chain. Android's Compose keyboard layout example uses a bottom spacer that responds to consumed system bar insets. Avoid mechanically adding full keyboard height and full navigation height, which can double-count overlapping space.
For Views, the software keyboard guide recommends android:windowSoftInputMode="adjustResize" for the best backward compatibility with its AndroidX implementation. Observe Type.ime() visibility and bounds. The manifest flag alone does not verify your screen's final layout.
Check intermediate and restored states
Record keyboard opening and dismissal, switching between text and numeric fields, and rotation while focused. A recording can reveal a button jumping through the keyboard even when both endpoint screenshots look correct. Use the documented keyboard animation APIs if the design requires synchronized motion.
Test at least one alternative keyboard on a real device where available. Suggestion rows and keyboard configurations change occupied space. After dismissal, expect the original bottom spacing and scroll behavior to return, without a leftover keyboard-sized gap or a duplicated navigation inset.
Exercise fullscreen content and separate windows
Edge-to-edge content and immersive fullscreen behavior are separate choices. Follow the immersive mode guide when hiding bars. In the photo viewer, reveal transient bars with the supported swipe and check the close action before, during, and after their appearance.
Open a floating confirmation dialog, a fullscreen dialog, and a bottom sheet if the app has them. Do not assume that a working activity supplies correct inset handling to every window or component. Check each surface's effective theme, content bounds, navigation background, and keyboard behavior.
For a dialog with text input, open the IME, submit, cancel, and reopen. Expect buttons and entered text to remain reachable. Return to the underlying form and verify restored bar appearance. A fullscreen route that changes icon contrast can leave the next screen unreadable if restoration is missing.
Capture expected and actual evidence and protect CI
Capture the full device window, including system bars, alongside any component screenshot. For every failure, record build, OS, target SDK, model, navigation mode, orientation, theme, keyboard, starting state, and exact actions. State the expected boundary and actual overlap in plain language.
A synthetic report might expect Save above the three-button area after keyboard dismissal, while the actual button remains behind it. Attach a screenshot and a recording of the unsuccessful tap. Use the mobile bug report guide to keep the report reproducible and redact entered data.
In CI, pin emulator image, density, window size, theme, navigation mode, and fixture data. Keep baselines per relevant configuration. Mask volatile clock pixels narrowly so an overlap in the toolbar cannot disappear inside a broad ignored region.
Add interaction assertions for the last field, save action, and dialog dismissal. Compare control bounds with the relevant current obstruction, using a common coordinate space. Wait for the intended IME and layout state instead of relying only on a fixed sleep. UI Automator supports tests involving device UI beyond the app.
Review screenshot baseline updates with the target SDK change. Preserve failing artifacts and require representative physical-device retests before release. A BetaRoast testing round can assign the same synthetic form journey across the missing device combinations.
Frequently asked questions
Is Android 16 edge-to-edge determined only by the OS?
No. Record both OS and target SDK. The target 36 opt-out works on Android 15 but is disabled on Android 16, so the same artifact can expose different layouts.
Should every screen add status and navigation padding?
No. Assign inset ownership per surface. Backgrounds may extend behind bars, while content needs protection. Existing components and parent containers may already account for a boundary.
Why does the keyboard leave a large empty gap?
Check duplicated IME and navigation spacing, raw inset padding, and listeners that accumulate padding. Reproduce opening and dismissal repeatedly and compare the restored geometry.
Can screenshot tests replace real-device interaction checks?
No. Screenshots establish appearance in a specific configuration. Physical taps, system gestures, keyboard transitions, and separate windows still need interaction evidence on representative devices.
Test the installed target SDK together with the device OS, then follow each screen through navigation modes, cutouts, keyboard transitions, and window changes. Give every inset a clear owner in Compose, Views, and mixed screens. Combine screenshots with real taps and geometry checks, preserve expected and actual evidence, and retest the failing matrix cell before approving a release.

