Flutter: how to prevent device orientation changes

2020-02-16 06:21发布

问题:

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

回答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



回答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());
    });
}


回答3:

For iOS, calling SystemChrome.setPreferredOrientations() doesn't work for me, and I had to change that in the Xcode project.



回答4:

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'



回答5:

Open android/app/src/main/AndroidManifest.xml and update 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">

with this code

<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">

It will work for android. For iOS, you can change from Xcode from this page https://i.stack.imgur.com/hswoe.png



回答6:

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()),
      );


回答7:

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());
}


标签: dart flutter