Flutter: Force portrait UI on tablets (iOS + Android) even when device is landscape, but avoid letterboxing / black bars

2 weeks ago 9
ARTICLE AD BOX

Yes, it is technically possible to achieve this, but it requires addressing platform-specific "multitasking" and "compatibility" features that override your code.

The reason you see rotation on iPad or letterboxing on Android tablets is that these systems prioritize "user flexibility" (split-screen, resizing) over an app's hard-coded orientation request. To force a "Portrait Fullscreen" experience even when the device is held sideways, you must effectively tell the OS: "This app cannot be resized or shared."


1. Fix for iOS (iPad)

On iPad, setPreferredOrientations is ignored if Multitasking (Split View/Slide Over) is enabled. If multitasking is on, the OS forces the app to support all orientations so it can fit into small side-windows.

The Solution: Opt-out of Multitasking

Open your project in Xcode.

Select your Runner target.

Under the General tab, find the Deployment Info section.

Check the box Requires full screen.

Note: This automatically adds <key>UIRequiresFullScreen</key><true/> to your Info.plist.

Ensure Landscape Left and Landscape Right are unchecked in the "Supported Interface Orientations (iPad)" section.

Result: The iPad will no longer rotate your UI. If the user holds the iPad in landscape, the UI stays in portrait. Because "Requires full screen" is on, the OS will not try to letterbox or resize the window; it treats the app as a fixed-orientation experience (common for games).


2. Fix for Android (Tablets)

Android tablets often use a "Compatibility Mode" for portrait-only apps, which causes the letterboxing (black bars) you’re seeing. To bypass this, you need to ensure the app is seen as "non-resizable" but "fullscreen-capable."

The Solution: Manifest Configuration

In your android/app/src/main/AndroidManifest.xml, update your <activity> tag:

XML

<activity android:name=".MainActivity" android:screenOrientation="portrait" android:resizeableActivity="false" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" ...>

android:screenOrientation="portrait": Hard-locks the activity at the OS level.

android:resizeableActivity="false": This is the "iPad equivalent." It tells Android not to allow the app into Split Screen mode. On many tablets, this prevents the system from "letterboxing" and forces the screen to stay in portrait.

[!IMPORTANT]

Android 15/16+ Change: Starting with recent Android versions, Google is making it harder to lock orientation on large screens (sw600dp+). If the system still letterboxes you, it is because the manufacturer (like Samsung or Google) is enforcing a "Reachability" policy.


3. Recommended "Hybrid" Approach

If you want to avoid the risks of being "rejected" for lack of tablet support or if the OS overrides your lock (common on newer Android foldables), the industry-standard "no-landscape-layout" workaround is:

Allow Landscape in the OS settings (Info.plist / Manifest).

Lock the UI rotation in Flutter. 3. Handle the "Sideways" look manually:

Dart

Widget build(BuildContext context) { return OrientationBuilder( builder: (context, orientation) { if (orientation == Orientation.landscape) { // If they turn it sideways, we still show the portrait UI // but centered or stretched to fill the screen. return Center( child: AspectRatio( aspectRatio: 9 / 16, // Force portrait ratio child: MyPortraitContent(), ), ); } return MyPortraitContent(); }, ); }
Read Entire Article