Flutter orientation lock: portrait only
In this article, I’ll try to provide full instruction how to setup orientation of Flutter app.
Another one? Why?
There are a lot of articles about it: one, two, three, four and much more. So why have I decided to write another one? It’s because I believe all these articles at least incomplete and at most — the provided solutions are just wrong.
Read on to understand what I’m talking about.
⚠️ Warning! I must warn you, there are a lot of heavy gifs in this article.
Introduction
Quite often an application is developed only for single orientation, for example — portrait. But by default an application changes orientation when you rotate a device:
To change this behaviour we need to explicitly define supported orientation.
Setup
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:
Pay attention to the following.
- You should call
setPreferredOrientation()
beforerunApp()
. - You shouldn’t call
runApp()
untilsetPreferredOrientation()
completes (it returnsFuture
). - You should call
WidgetsFlutterBinding.ensureInitialized()
(docs) beforesetPreferredOrientation()
call.
It’s not the only option to use setPreferredOrientation()
, but I would recommend to do it in this way.
Now we have desired behaviour on device rotation:
Everything seems fine, but really it’s not. And that is the main reason of the article. There is a thing: this method works only when Flutter runs, i.e. before Flutter starts an orientation of application is not locked. Yes, I’m talking about launch screen. So, if we launch the application from an album orientation, then we got this:
And on Android as well:
I hate it. To fix this we need to setup orientation in the native part of the app. Let’s do it.
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>
As a result, now we can see a correct orientation immediately after launch:
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>
After that we have desired behaviour on Android:
And that’s all. Here is the repository with an example app:
Hope the article was helpful. Any corrections or additions are welcome. Goodbye and have a nice day ✌️