Flattern: Wie kann man Änderungen der Geräteorientierung verhindern und das Porträt erzwingen?


120

Ich möchte verhindern, dass meine Anwendung ihre Ausrichtung ändert, und das Layout zwingen, sich an "Hochformat" zu halten.

Im main.dart habe ich gesetzt:

void main(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]);
  runApp(new MyApp());
}

aber wenn ich die Android Simulator-Drehtasten benutze, "folgt" das Layout der neuen Geräteorientierung ...

Wie könnte ich das lösen?

Vielen Dank


4
Angenommen, Sie haben importiert 'package:flutter/services.dart', dann ist es vielleicht ein Fehler: github.com/flutter/flutter/issues/13238
Brian Kung

Ich bin mir nicht sicher, warum dir das passiert. Ich habe versucht, Ihren Code auf einem Emulator und auch auf meinem eigenen Gerät auszuführen, und es funktioniert einwandfrei.
Hemanth Raj

SystemChrome.setPreferredOrientationskehrt asynchron zurück, scheint runAppalso in a eingeschlossen zu sein then.
Ken

Antworten:


184

package:flutter/services.dartDann importieren

Lege das SystemChrome.setPreferredOrientations Innere der Widget build()Methode ein.

Beispiel:

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
        DeviceOrientation.portraitDown,
      ]);
      return new MaterialApp(...);
    }
  }

Aktualisieren

Diese Lösung funktioniert möglicherweise nicht für einige IOS-Geräte, wie in der aktualisierten Flatterdokumentation vom Oktober 2019 erwähnt.

Sie empfehlen, die Ausrichtung zu korrigieren, indem Sie UISupportedInterfaceOrientations in Info.plist wie folgt festlegen

<array>
    <string>UIInterfaceOrientationPortrait</string>
</array>

Weitere Informationen finden Sie unter https://github.com/flutter/flutter/issues/27235#issuecomment-508995063


Hat funktioniert. Vielen Dank <3
Suthura Sudharaka

72

@boeledi, Wenn Sie die Ausrichtung des Geräts „sperren“ und nicht ändern möchten, während der Benutzer sein Telefon dreht, wurde dies wie folgt eingestellt:

// This did not work as requirement
void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  runApp(new MyApp());
}

Sie müssen warten, bis setPreferredOrientationsder Vorgang abgeschlossen ist, und dann die App starten

// This will works always for lock screen Orientation.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}

Beim Kompilieren tritt manchmal ein Fehler auf. Sie sollten native Lösungen verwenden. Das Hinzufügen von 'android: screenOrientation = "Porträt" zu MainActivity auf AndroidManifest, wie von Abeer Iqbal vorgeschlagen, hat für mich auf Android funktioniert.
Tincho825

44

iOS:

Das Anrufen SystemChrome.setPreferredOrientations()funktioniert bei mir nicht und ich musste das Device Orientationim Xcode-Projekt wie folgt ändern :

Geben Sie hier die Bildbeschreibung ein

Android:

Setzen Sie das screenOrientationAttribut portraitfür die Hauptaktivität in der Datei android/app/src/main/AndroidManifest.xmlwie folgt:

Geben Sie hier die Bildbeschreibung ein


Ich hatte das gleiche Problem. Hast du es auf einem iPad ausgeführt? Ich habe nur auf einem iPad getestet und dies scheint ein Problem zu sein: github.com/flutter/flutter/issues/27235
Boy

android: Dieses Attribut wurde in API Level 24 hinzugefügt.
BloodLoss

Ich benutze screenOrientationseit API Level 8 für Android. @BloodLoss, ich denke du hast es in den Dokumenten gelesen, aber über resizeableActivityAttribute. Überprüfen Sie den Link erneut. ^^
Erick M. Sprengel

22

Die Methode 'setPreferredOrientations' gibt ein Future-Objekt zurück. Pro Dokumentation stellt eine Zukunft einen Wert dar, der irgendwo in Zukunft verfügbar sein wird. Deshalb sollten Sie warten, bis es verfügbar ist, und dann mit der Anwendung fortfahren. Daher soll eine "dann" -Methode verwendet werden, die per Definition "Rückrufe registriert, die aufgerufen werden sollen, wenn die Zukunft abgeschlossen ist". Daher sollten Sie diesen Code verwenden:

  void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
      runApp(new App());
    });
   }

Außerdem muss die folgende Datei importiert werden:

'package: flutter / services.dart'


Ich kann bestätigen, dass dies funktioniert. Verwenden Sie jedoch whenComplete () anstelle von then (), wenn die Funktion keinen Parameter erhalten hat.
Csaba Gergely

20

Öffnen Sie android / app / src / main / AndroidManifest.xml und fügen Sie die folgende Zeile in die MainActivity ein:

android:screenOrientation="portrait"

Wenn Sie dies haben:

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

Sie sollten am Ende so etwas haben:

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

Dies funktioniert für Android. Unter iOS müssen Sie dies auf der Xcode-Seite ändern: https://i.stack.imgur.com/hswoe.png (wie Hejazi sagte)


danke, erinnere dich daran, dass die Reihenfolge von "Porträt" nach der configChanges "Ausrichtung" wichtig ist.
MR_AMDEV

13

Importieren Sie dies zunächst in die Datei main.dart

import 'package:flutter/services.dart';

Dann kopieren Sie nicht Einfügen, sondern sehen (merken) und schreiben den folgenden Code in die Datei main.dart

So erzwingen Sie im Hochformat :

void main() {
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp,DeviceOrientation.portraitDown])
      .then((_) => runApp(MyApp()),
  );

Um zu erzwingen , in Landschaftsmodus:

   void main() {
      SystemChrome.setPreferredOrientations(
          [DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight])
          .then((_) => runApp(MyApp()),
      );

1
Vielen Dank, dass Sie die Leute daran erinnert haben, nicht blind zu kopieren und einzufügen
Ryan,

1
Ich verstehe, warum Sie NICHT gebeten haben, das Einfügen zu kopieren ... das Ende} fehlt ... Ich kopiere eingefügt ... :)
rohan koshti

12

Geben Sie WidgetsFlutterBinding.ensureInitialized () ein, da sonst beim Erstellen eine Fehlermeldung angezeigt wird.

import 'package:flutter/services.dart';

    void main() async => {
          WidgetsFlutterBinding.ensureInitialized(),

          await SystemChrome.setPreferredOrientations(
              [DeviceOrientation.portraitUp]), // To turn off landscape mode

          runApp(MainApp())
        };

4

setPreferredOrientationgibt a zurück Future<void>, ist also asynchron. Der am besten lesbare Ansatz besteht darin, mainasynchron zu definieren :

Future<void> main() async {
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  return runApp(new MyApp());
}

3
Ich bin absolut anderer Meinung. awaitist ein allgegenwärtiges Programmiermuster, das in mehreren Sprachen vorhanden ist, und es ist sehr klar, was ausdrucksstark ist. thenerstellt Verschachtelungsebenen. Wenn Sie drei oder vier Fortsetzungen haben, wird thenes in der Tat sehr schwer zu lesen.
Rob Lyndon

.thenkann verkettet werden, anstatt zu verschachteln, wie es a erwartet FutureOr. Dies ermöglicht mir einen funktionaleren Ansatz, der lesbarer und eleganter ist. Zum Beispiel kann ich den Ausdruckskörper anstelle des in Klammern gesetzten Körpers verwenden, indem ich die "Thens" verkette.
Mateus Felipe

Beim Kompilieren tritt manchmal ein Fehler auf. Sie sollten native Lösungen verwenden. Das Hinzufügen von 'android: screenOrientation = "Porträt" zu MainActivity auf AndroidManifest, wie von Abeer Iqbal vorgeschlagen, hat für mich auf Android funktioniert.
Tincho825

Wenn ein Fehler auftritt: "Nicht behandelte Ausnahme: Auf ServicesBinding.defaultBinaryMessenger wurde zugegriffen, bevor die Bindung initialisiert wurde." Versuchen Sie es mit diesem Fix: stackoverflow.com/questions/57689492/…
Fillipe Silva vor

1

Ab neuen Flatterversionen preferred Orientationmüssen wir zusammen mit der Einstellung eine zusätzliche Zeile hinzufügen, d. H.

 WidgetsFlutterBinding.ensureInitialized();

Der Arbeitscode dafür lautet also -

import 'package:flutter/services.dart';
    void main() {
          WidgetsFlutterBinding.ensureInitialized();
          SystemChrome.setPreferredOrientations([
            DeviceOrientation.portraitUp,
            DeviceOrientation.portraitDown
          ]);
          runApp(MyApp());
        }

0

Versuchen

 void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await SystemChrome.setPreferredOrientations(
          [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); 
    
      runApp(MyApp());
 }

Sie können auch die Einstellungen für die Bildschirmausrichtung im Android-Manifest und in der Datei ios info.plist ändern.


0

Import import 'package: flutter / services.dart';

Dann fügen Sie die folgende Codezeile in Ihre main.dart-Datei und in Ihre Hauptmethode wie folgt ein:

WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitDown,
    DeviceOrientation.portraitUp,
  ]);

runApp(myApp());


-3

Die beste Lösung besteht darin, es in der Erstellungsmethode von MyApp () zu verwenden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.