Reputation: 7567
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
Upvotes: 365
Views: 266585
Reputation: 6821
@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 required
void main() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
runApp(new MyApp());
}
You have to wait until
setPreferredOrientations
is done and then start the app
// This will always work for lock screen Orientation.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
runApp(new MyApp());
}
Upvotes: 178
Reputation: 1111
First of all import this in main.dart file
import 'package:flutter/services.dart';
Then don't copy paste rather see(remember) and write below code in main.dart file
To force in portrait mode:
void main() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp,DeviceOrientation.portraitDown])
.then((_) => runApp(MyApp()),
);
}
To force in landscape mode:
void main() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight])
.then((_) => runApp(MyApp()),
);
}
Upvotes: 19
Reputation: 5479
One scenario where SystemChrome.setPreferredOrientations()
won't work (even on iPhone) is where - for whatever reason - you have put your FlutterViewController
inside a UINavigationController
.
In this case, as is expected iOS behaviour, it is the UINavigationController
which is responsible for handling orientation changes, not the FlutterViewController
(which is why SystemChrome.setPreferredOrientations()
won't work).
To force a given orientation in this case, you should therefore subclass the UINavigationController
and specify the orientations you wish to support:
class MyNavigationController: UINavigationController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { .portrait }
}
Upvotes: 0
Reputation: 6931
If your camera screen is still rotate in some case (iPhone 14 Plus, my case), after setting
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); in
App Startup dart file then add below code where you initiate camera controller.
await cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp);
Upvotes: 0
Reputation: 7225
To force portrait in iPad, you also have to modify key UISupportedInterfaceOrientations~ipad
in ios/Runner/Info.plist
:
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
This can also be done through XCode.
Above will work locally. In order to upload to the App Store through XCode, you also have the add the following to Info.plist
. This can also be done by checking "Requires full screen" under Target->General->Deployment Info.
<key>UIRequiresFullScreen</key>
<true/>
Otherwise you'll get an error while uploading.
Upvotes: 4
Reputation: 6022
Flutter orientation lock: portrait only
In Flutter we have SystemChrome.setPreferredOrientation() (see documentation) to define preferred orientation. Exactly this method you can find in all those articles about setup orientation in Flutter. Let’s see how we can use it:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
// We need to call it manually,
// because we going to call setPreferredOrientations()
// before the runApp() call
WidgetsFlutterBinding.ensureInitialized();
// Than we setup preferred orientations,
// and only after it finished we run our app
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((value) => runApp(MyApp()));
}
iOS
Open project in Xcode (ios/Runner.xcworkspace)
, choose Runner
in the project navigator, select Target Runner
and on Tab General
in section Deployment Info
we can setup Device Orientation:
Also, we can do it manually without opening Xcode at all — just edit ios/Runner/Info.plist
. Open it as a text file, find key UISupportedInterfaceOrientation
and leave only desired values:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
Android
To define orientation for Android
we need to edit ApplicationManifest
. Open android/app/src/main/AndroidManifest.xml
and add an attribute screenOrientation for a main
activity:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.orientation_lock_example">
<application ...>
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
...
/>
...
</activity>
...
</application>
</manifest>
And that’s all. Here is the repository with an example app:
Hope this was helpful.
Upvotes: 14
Reputation: 97
Import import 'package:flutter/services.dart';
Then you include the line of code below in your main.dart
file, and in your main method like so:
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitDown,
DeviceOrientation.portraitUp,
]);
runApp(myApp());
Upvotes: 9
Reputation: 737
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());
};
Upvotes: 60
Reputation: 3059
You have two options for for android
1. Write for on main
main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(
child: MyApp(),
);
});
}
2. Set from natively on AndroidManifest.xml
file
You have also two option for iOS
1. from info.plist
add this line to your info.plist
file
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
2. from Runner
open your Runner.xcworkspace
from iOS folder on your Xcode. Click on Runner not Pods. You can find this option on General>Deployment Info. just check what you want
Upvotes: 6
Reputation: 4289
This is simple way ->
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
Upvotes: 0
Reputation: 1292
To make SystemChrome.setPreferredOrientations
to work on iPad, enable "Requires full screen" in Xcode project editor or simply add the following lines in /ios/Runner/Info.plist in your project folder.
<key>UIRequiresFullScreen</key>
<true/>
Upvotes: 0
Reputation: 367
It's possible to enable the requires fullscreen
option in iOS case.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]).then((_) {
runApp(MediaQuery(
data: MediaQueryData(),
child:
MaterialApp(debugShowCheckedModeBanner: false, home: LoginPage())));
});
}
Upvotes: 2
Reputation: 1465
For people, that they are reading this question now. The easiest way that I found and it worked on both android & ios devices.
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
],
).then((val) {
runApp(YourAppName());
});
}
Upvotes: 9
Reputation: 117
This solution has worked for me on two different projects for Android. Can't guarantee it will work for iOS too. I've read all the previous answers and I think the best and simplest solution is to do it like this:
This way you avoid all the "await"s, "async"s and "then"s that might mess around with your code
/// this is in main.dart
main(){
WidgetsFlutterBinding.ensureInitialized();
runApp(
MaterialApp(
initialRoute: '/root',
routes: {
'/root': (context) => MyApp(),
},
title: "Your App Title",
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// ENFORCE DEVICE ORIENTATION PORTRAIT ONLY
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
/// RUN THE APP
return MaterialApp(
home: HomeScreen(),
);
}
}
I think this answer's update is your best bet for iOS.
!! DISCLAIMER !! I did a little bit of research and apparently, the documentation here specifically says:
setPreferredOrientations method Limitations:
"This setting will only be respected on iPad if multitasking is disabled."
Here is how you can disable multitasking (AKA turn on "Requires Full Screen" option) from XCode
You might also try this one out. I haven't tried it personally, since I don't have an iPad or XCode on my PC, but it's worth a shot
Upvotes: 1
Reputation: 85
If you are editing this from the xcode interface, it will not be changed for ipad. For the ipad section, you must edit the info.plist file from the android studio. You can see in the array list like that "~ ipad". There are two sections available in info.plist, you have to manually edit it for both iphone and ipad.
Upvotes: 0
Reputation: 666
Just add the following line of code in the main.dart file.
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
and remember to import services.dart file. An example is given below!
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
home: Scaffold(
body: Center(child: Text("A Flutter Example!")),
),
);
}
}
Upvotes: 6
Reputation: 187
Below is the official example of the flutter team. https://github.com/flutter/samples/blob/master/veggieseasons/lib/main.dart
import 'package:flutter/services.dart' show DeviceOrientation, SystemChrome;
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(HomeScreen());
}
Upvotes: 4
Reputation: 2574
Try
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
runApp(MyApp());
}
You can also change the screen orientation settings in the android manifest and ios info.plist file.
Upvotes: 2
Reputation: 1630
As of new flutter versions along with setting the preferred Orientation
we need to add one extra line i.e
WidgetsFlutterBinding.ensureInitialized();
So working code for this is -
import 'package:flutter/services.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
runApp(MyApp());
}
Upvotes: 1
Reputation: 1346
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.sstatic.net/hswoe.png (as Hejazi said)
Upvotes: 70
Reputation: 17015
Calling SystemChrome.setPreferredOrientations()
doesn't work for me, and I had to change the Device Orientation
in the Xcode project as following:
Set the screenOrientation
attribute to portrait
for the main activity in the file android/app/src/main/AndroidManifest.xml
as following:
Upvotes: 141
Reputation: 4735
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
Upvotes: 443
Reputation: 12681
setPreferredOrientation
returns a Future<void>
, so it is asynchronous. The most readable approach is to define main
as asynchronous:
Future<void> main() async {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
return runApp(new MyApp());
}
Upvotes: 5
Reputation: 507
The 'setPreferredOrientations' method returns a Future object. Per documentation a Future represents some value that will be available somewhere in future. That's why you shall wait until it's available and then move on with the application. Hence, there shall be used 'then' method, which, per definition, "registers callbacks to be called when the Future completes". Hence, you shall use this code:
void main() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
runApp(new App());
});
}
Also, the following file must be imported:
'package:flutter/services.dart'
Upvotes: 28