Flutter: how to prevent device orientation changes and force portrait?
Solution 1
Import package:flutter/services.dart
, then
Put the SystemChrome.setPreferredOrientations
inside the Widget build()
method.
Example:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return new MaterialApp(...);
}
}
Update
This solution mightn't work for some IOS devices as mentioned in the updated flutter documentation on Oct 2019.
They Advise to fixed the orientation by setting UISupportedInterfaceOrientations in Info.plist like this
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
For more information https://github.com/flutter/flutter/issues/27235#issuecomment-508995063
Solution 2
@boeledi, If you want to “lock” the device orientation and not allow it to change as the user rotates their phone, this was easily set as below,
// This did not work as requirement
void main() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(new MyApp());
}
You have to wait until
setPreferredOrientations
is done and then start the app
// This will works always for lock screen Orientation.
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(new MyApp());
});
}
Solution 3
iOS:
Calling SystemChrome.setPreferredOrientations()
doesn't work for me, and I had to change the Device Orientation
in the Xcode project as following:
Android:
Set the screenOrientation
attribute to portrait
for the main activity in the file android/app/src/main/AndroidManifest.xml
as following:
Solution 4
Put the WidgetsFlutterBinding.ensureInitialized()
else you will get an error while building.
import 'package:flutter/services.dart';
void main() async => {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp],
); // To turn off landscape mode
runApp(MainApp());
};
Solution 5
Open android/app/src/main/AndroidManifest.xml and add the following line in the MainActivity:
android:screenOrientation="portrait"
If you have this:
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
You should end up with something like this:
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
This works for Android. On iOS, you will have to change this from the Xcode page: https://i.stack.imgur.com/hswoe.png (as Hejazi said)
Related videos on Youtube
boeledi
Updated on December 26, 2021Comments
-
boeledi over 2 years
I would like to prevent my application from changing its orientation and force the layout to stick to "portrait".
In the main.dart, I put:
void main(){ SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown ]); runApp(new MyApp()); }
but when I use the Android Simulator rotate buttons, the layout "follows" the new device orientation...
How could I solve this?
Thanks
-
Brian Kung about 6 yearsAssuming you imported
'package:flutter/services.dart'
, then maybe it's a bug: github.com/flutter/flutter/issues/13238 -
Hemanth Raj about 6 yearsNot sure why this happens to you. I tried running your code on an emulator and also my own device and it works fine.
-
user3162901 about 4 years
SystemChrome.setPreferredOrientations
returns asynchronously, so seems likerunApp
should be enclosed in athen
.
-
-
Boy over 4 yearsI had the same problem, did you run it on an iPad? I only tested on an iPad and this seems to be an issue: github.com/flutter/flutter/issues/27235
-
Rob Lyndon over 4 yearsI strongly disagree.
await
is a ubiquitous programming pattern that is present in multiple languages, and it's very clear what expressive.then
creates levels of nesting. If you have three or four continuations,then
starts to become very difficult to read indeed. -
Mateus Felipe over 4 years
.then
can be chained instead of nesting, as it expects aFutureOr
. This allows me to use a more functional approach, which is more readable and elegant. For example, I can use expression body instead of bracketed body by chaining the "thens". -
Tincho825 about 4 yearsIt sometimes throws an error while compiling, you should use native solutions. Adding 'android:screenOrientation="portrait"' to MainActivity on AndroidManifest as Abeer Iqbal's suggests worked for me on Android.
-
Tincho825 about 4 yearsIt sometimes throws an error while compiling, you should use native solutions. Adding 'android:screenOrientation="portrait"' to MainActivity on AndroidManifest as Abeer Iqbal's suggests worked for me on Android.
-
MR_AMDEV about 4 yearsthanks ,REMEMBER the order of "portrait" after the configChanges "orientation" does matter.
-
BIS Tech about 4 yearsandroid: This attribute was added in API level 24.
-
Ryan almost 4 yearsThank you for reminding people not to copy-paste blindly
-
rohan koshti almost 4 yearsI see why you asked NOT to copy paste ... the ending } is missing... I copy pasted... :)
-
Csaba Gergely almost 4 yearsI can confirm this works. But use whenComplete() instead of then(), when the function got no param.
-
Erick M. Sprengel almost 4 yearsI use
screenOrientation
since API level 8 for Android. @BloodLoss , I think you read it on the docs, but aboutresizeableActivity
attribute. Check the link again. ^^ -
Fillipe Silva almost 4 yearsIf you are facing an error: "Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized." try using this fix: stackoverflow.com/questions/57689492/…
-
Golden Lion almost 4 yearsIf you put SystemChrome.setPreferredOrientations in main you will get the error: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized. Inserting the code in build works because bindings have been initialized at this point.
-
RyanNa about 3 yearsReminder that for iOS info.plist, you have to set it for iPad as well under <key>UISupportedInterfaceOrientations~ipad</key>
-
mLstudent33 over 2 yearsThis worked perfectly on Flutter 2.5 except the Android status bar I was hiding has returned.
-
mLstudent33 over 2 yearsI hid the Android task bar with
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]);
and adding this makes it appear again for a moment and then it goes away when I tap something to navigate. Is this by design? I have the above snippet nested in void initState() for whichever page I want to hide Android task bar and your snippet in build of my top level screen that main runs. -
ÄR Âmmãř Żąîñh over 2 years@Boy you should change this configuration on info.plist for ipad <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UIInterfaceOrientationPortrait</string> </array>
-
Johan about 2 yearscleanest way so far