Flutter orientation lock: portrait only

Roman Volkov
3 min readJul 27, 2020

--

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:

Changing an orientation on the device rotation.

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() before runApp().
  • You shouldn’t call runApp() until setPreferredOrientation() completes (it returns Future).
  • You should call WidgetsFlutterBinding.ensureInitialized() (docs) before setPreferredOrientation() 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:

The device is rotated, but app content does not.

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:

The application changes orientation after the launch.

And on Android as well:

Android has the same behaviour.

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:

Setup a device orientation in Xcode.

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:

Final result on IPhone.

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:

Final result on Android phone.

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 ✌️

--

--