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

Boeledi
quelle
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

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

Hejazi
quelle
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'

Ara Mkrtchyan
quelle
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)

Abeer Iqbal
quelle
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()),
      );
Pinkesh Darji
quelle
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())
        };
Strich
quelle
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());
}
Rob Lyndon
quelle
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());
        }
B. Shruti
quelle
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.

Bukunmi
quelle
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());
Silas Ogar
quelle
0

Unten ist das offizielle Beispiel des Flatterteams. 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());
}
Lucas Martins Soares
quelle
-3

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

Aashar Wahla
quelle