Flutter Edge-to-Edge on Android 15 and 16: Why the Opt-Out Ends and How to Fix Your Layouts (2026)
What changes for Flutter apps with edge-to-edge on Android 15 and 16?
Once your app targets Android 15 (API 35), it draws edge-to-edge on Android 15 and later devices. The window extends behind the status bar and the navigation bar, and your layout has to handle the insets. On Android 15 you could opt out with the windowOptOutEdgeToEdgeEnforcement style attribute. For apps targeting Android 16 (API 36), Google has deprecated and disabled that attribute, so on Android 16 devices the opt-out no longer works. Flutter apps target Android 15 by default from Flutter 3.27. Google Play now requires API 36 for new apps and updates, with extensions running only to 1 November 2026. So edge-to-edge is no longer something you can switch off. It's part of every release.
This is the checklist I use for my own Flutter apps (CoinDrop, Swappr and IOU): what moves, where Flutter already helps, the screens that usually break, and how to test before a release.
The rules, in order
| Your target | On Android 15 devices | On Android 16 devices |
|---|---|---|
| API 34 or lower | Not enforced | Not enforced |
| API 35 | Edge-to-edge enforced; opt-out attribute works | Edge-to-edge enforced; opt-out attribute works |
| API 36 | Edge-to-edge enforced; opt-out still works on this device | Edge-to-edge enforced; opt-out is disabled |
Android's behavior-change notes for 16 spell out the last row. If your app targets API 36 and runs on Android 16, windowOptOutEdgeToEdgeEnforcement is disabled. Google's advice is to remove the attribute and support edge-to-edge on Android 15 too. Flutter's breaking-change page adds a warning: using the opt-out mechanism on Android 16 or later might crash your app. If you still need it on 15 for a while, put it in version-specific resources.
The Play deadline is what makes this urgent. My guide to the target API 36 deadline and the 1 November extension covers the Play side. This page is about making the UI ready for it.
What actually moves on screen
With edge-to-edge, the system bars are drawn on top of your app instead of beside it. Android's edge-to-edge guide lists three kinds of overlap to handle:
- System bar insets. The status bar at the top and the navigation bar at the bottom. Tappable content must not sit underneath them.
- Display cutout insets. The camera notch or hole. In landscape it can be on the side.
- System gesture insets. The bottom edge used for the home gesture and the side edges used for back. Swipeable content near those edges fights the system.
The status bar and gesture navigation bar become transparent. With 3-button navigation, the navigation bar gets a translucent scrim. So a layout can look fine with gesture navigation and still hide a button behind the scrim with 3-button navigation. Test both.
Where Flutter already helps
Flutter has handled insets for a long time, and many apps need little work. On Android, the system bars and cutout reach your widgets as padding in MediaQuery. Some widgets account for it automatically:
Scaffoldwith anAppBar. The app bar extends behind the status bar and pads its contents below it.- Material bottom navigation.
NavigationBarandBottomNavigationBaraccount for the bottom inset. SafeArea. It insets its child by the padding the system reports. You can turn off individual sides withtop,bottom,leftandright.
The problems usually come from custom layouts: a screen with no app bar, a custom bottom bar, a full-screen image or map, a bottom sheet, or a button pinned to the bottom with Positioned or Align.
Six screens that usually break
- Screens without an AppBar. Login, onboarding and splash-like screens put their first widget under the status bar. Wrap the body in
SafeArea, or pad the top withMediaQuery.paddingOf(context).top. - Custom bottom bars and pinned buttons. A "Continue" button at the very bottom ends up under the navigation bar. Add the bottom padding, or wrap it in
SafeArea(top: false). - Lists that end under the navigation bar. The last item can't be tapped. Add bottom padding to the list instead of wrapping the whole list in
SafeArea, so content can still scroll behind the bar. - Full-screen media. Images and maps should usually fill the screen. Keep the controls, like back and share buttons, inside the safe area.
- Bottom sheets and dialogs. Check that sheet content clears the navigation bar. A sheet that sizes itself to its content needs bottom padding too.
- Status bar icon contrast. With a transparent status bar, white icons on a white background disappear. Set
systemOverlayStyleon theAppBar, or wrap screens without an app bar inAnnotatedRegion<SystemUiOverlayStyle>.
Removing the opt-out cleanly
If you followed Flutter's 3.27 migration note and added android:windowOptOutEdgeToEdgeEnforcement to LaunchTheme and NormalTheme, plan to remove it before you target API 36:
- Search
android/app/src/main/res/forwindowOptOutEdgeToEdgeEnforcement. Checkvalues,values-nightand anyvalues-v35orvalues-35folders. - Fix the screens listed above first, while the opt-out still applies on your Android 15 test device. Then delete the attribute everywhere.
- If you call
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge), you can keep it. It's the behaviour Android now enforces anyway, and it also makes older Android versions match. - Bump
targetSdk, build a release bundle and test on both Android 15 and Android 16.
Doing it in this order means you never ship a build where the opt-out silently stops working on some devices and not others.
A 20-minute test plan
You don't need a device lab. An emulator with Android 16 and one with Android 15 cover most of it:
- Both navigation modes. Switch between gesture navigation and 3-button navigation in system settings and walk your main flows in each.
- A cutout. Use the display cutout simulation in Developer options, then rotate to landscape.
- The keyboard. Open every text field near the bottom of a screen.
MediaQuery.viewInsetsOf(context).bottomis the keyboard height.Scaffoldresizes for it by default unless you turnedresizeToAvoidBottomInsetoff. - Light and dark theme. Check status bar icon contrast in both.
- Screenshots for Play. If your store screenshots show the old layout with solid bars, update them after the change.
I add these checks to my Flutter and Firebase release checklist for Google Play. I also ship the first API 36 build with a staged rollout, so a layout bug reaches a small share of users first.
Same release, other checks
The API 36 bump usually lands alongside other platform work. The 16 KB page size requirement affects native libraries rather than layout, but both show up when you upgrade Flutter, AGP and plugins at once. Predictive back is also enabled by default for apps targeting 16 on Android 16 devices, so test your back navigation in the same pass.
FAQ
Can I still opt out of edge-to-edge in a Flutter app?
Only while you target API 35, or on Android 15 devices. For apps targeting Android 16, the opt-out attribute is deprecated and disabled on Android 16 devices, and Flutter warns that using it there might crash your app.
Does SafeArea fix everything?
It fixes overlap, but wrapping whole screens can look wrong: content stops at the bars instead of scrolling behind them. Use it for controls, and use padding from MediaQuery for scrolling content.
Which Flutter version made apps edge-to-edge by default?
Flutter 3.27. From that release, apps using the default flutter.targetSdkVersion target Android 15, which opts them in to edge-to-edge on Android 15 devices.
Do I need to change anything for iOS?
Not for this change. It's an Android behaviour. The same SafeArea and MediaQuery padding also handle the notch and home indicator on iOS.
Sources
- Android 16 behavior changes: edge-to-edge opt-out going away (checked 2026-10-27)
- Android developers: display content edge-to-edge, insets and system bars (checked 2026-10-27)
- Flutter breaking change: SystemUiMode defaults to edge-to-edge (checked 2026-10-27)
- Flutter API: SafeArea class (checked 2026-10-27)