Flutter: comment éviter les changements d'orientation de l'appareil et forcer le portrait?

124

Je voudrais empêcher mon application de changer son orientation et forcer la mise en page à coller à "portrait".

Dans le main.dart, j'ai mis:

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

mais lorsque j'utilise les boutons de rotation du simulateur Android, la disposition "suit" l'orientation du nouvel appareil ...

Comment pourrais-je résoudre ça?

Merci

Boeledi
la source
4
En supposant que vous ayez importé 'package:flutter/services.dart', alors peut-être que c'est un bug: github.com/flutter/flutter/issues/13238
Brian Kung
Je ne sais pas pourquoi cela vous arrive. J'ai essayé d'exécuter votre code sur un émulateur et aussi sur mon propre appareil et cela fonctionne bien.
Hemanth Raj
SystemChrome.setPreferredOrientationsrenvoie de manière asynchrone, il semble donc que runAppdevrait être inclus dans un fichier then.
Ken

Réponses:

193

Importez package:flutter/services.dart, puis

Mettez l' SystemChrome.setPreferredOrientationsintérieur de la Widget build()méthode.

Exemple:

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

Mettre à jour

Cette solution peut ne pas fonctionner pour certains appareils IOS, comme mentionné dans la documentation mise à jour du flutter d'octobre 2019.

Ils conseillent de fixer l'orientation en définissant UISupportedInterfaceOrientations dans Info.plist comme ceci

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

Pour plus d'informations https://github.com/flutter/flutter/issues/27235#issuecomment-508995063

le maçon
la source
Travaillé. Merci <3
Suthura Sudharaka
1
Si vous mettez SystemChrome.setPreferredOrientations dans main, vous obtiendrez l'erreur: ServicesBinding.defaultBinaryMessenger a été accédé avant l'initialisation de la liaison. L'insertion du code dans la génération fonctionne car les liaisons ont été initialisées à ce stade.
Golden Lion
77

@boeledi, si vous souhaitez «verrouiller» l'orientation de l'appareil et ne pas l'autoriser à changer lorsque l'utilisateur fait pivoter son téléphone, cela a été facilement défini comme ci-dessous,

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

Vous devez attendre que ce setPreferredOrientationssoit terminé, puis démarrer l'application

// This will works always for lock screen Orientation.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}
TejaDroid
la source
Il génère parfois une erreur lors de la compilation, vous devez utiliser des solutions natives. L'ajout de 'android: screenOrientation = "portrait"' à MainActivity sur AndroidManifest comme le suggère Abeer Iqbal a fonctionné pour moi sur Android.
Tincho825
44

iOS:

L'appel SystemChrome.setPreferredOrientations()ne fonctionne pas pour moi, et j'ai dû changer le Device Orientationdans le projet Xcode comme suit:

entrez la description de l'image ici

Android:

Définissez l' screenOrientationattribut sur portraitpour l'activité principale du fichier android/app/src/main/AndroidManifest.xmlcomme suit:

entrez la description de l'image ici

Hejazi
la source
J'ai eu le même problème, l'avez-vous exécuté sur un iPad? Je n'ai testé que sur un iPad et cela semble être un problème: github.com/flutter/flutter/issues/27235
Boy
android: cet attribut a été ajouté au niveau de l'API 24.
BloodLoss
J'utilise screenOrientationdepuis le niveau d'API 8 pour Android. @BloodLoss, je pense que vous l'avez lu sur la documentation, mais à propos de l' resizeableActivityattribut. Vérifiez à nouveau le lien. ^^
Erick M. Sprengel le
22

La méthode 'setPreferredOrientations' renvoie un objet Future. Par documentation, un Future représente une valeur qui sera disponible quelque part dans le futur. C'est pourquoi vous devez attendre qu'il soit disponible, puis passer à l'application. Par conséquent, il doit être utilisé la méthode «alors», qui, par définition, "enregistre les rappels à appeler lorsque le futur se termine". Par conséquent, vous utiliserez ce code:

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

De plus, le fichier suivant doit être importé:

'package: flutter / services.dart'

Ara Mkrtchyan
la source
Je peux confirmer que cela fonctionne. Mais utilisez whenComplete () au lieu de then (), lorsque la fonction n'a pas de paramètre.
Csaba Gergely le
20

Ouvrez android / app / src / main / AndroidManifest.xml et ajoutez la ligne suivante dans MainActivity:

android:screenOrientation="portrait"

Si vous avez ceci:

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

Vous devriez vous retrouver avec quelque chose comme ça:

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

Cela fonctionne pour Android. Sur iOS, vous devrez changer cela depuis la page Xcode: https://i.stack.imgur.com/hswoe.png (comme l'a dit Hejazi)

Abeer Iqbal
la source
merci, RAPPELEZ-VOUS que l'ordre de "portrait" après le "orientation" de configChanges importe.
MR_AMDEV le
13

Tout d'abord importez ceci dans le fichier main.dart

import 'package:flutter/services.dart';

Ensuite , ne copiez pas collez plutôt voyez (rappelez-vous) et écrivez le code ci-dessous dans main.dart fichier

Pour forcer en mode portrait :

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

Pour forcer en mode paysage :

   void main() {
      SystemChrome.setPreferredOrientations(
          [DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight])
          .then((_) => runApp(MyApp()),
      );
Pinkesh Darji
la source
1
Merci d'avoir rappelé aux gens de ne pas copier-coller à l'aveuglette
Ryan
1
Je vois pourquoi vous avez demandé de NE PAS copier-coller ... la fin} est manquante ... J'ai copié-collé ... :)
rohan koshti
n'a pas fonctionné pour le flutter chrome
Golden Lion
13

Mettez WidgetsFlutterBinding.ensureInitialized () sinon vous obtiendrez une erreur lors de la construction.

import 'package:flutter/services.dart';

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

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

          runApp(MainApp())
        };
Tiret
la source
5

setPreferredOrientationrenvoie a Future<void>, donc il est asynchrone. L'approche la plus lisible consiste à définir maincomme asynchrone:

Future<void> main() async {
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  return runApp(new MyApp());
}
Rob Lyndon
la source
3
Je suis fortement en désaccord. awaitest un modèle de programmation omniprésent qui est présent dans plusieurs langages, et ce qui est expressif est très clair. thencrée des niveaux d'imbrication. Si vous avez trois ou quatre suites, cela thencommence à devenir très difficile à lire.
Rob Lyndon le
.thenpeut être enchaîné au lieu de s'emboîter, car il attend un fichier FutureOr. Cela me permet d'utiliser une approche plus fonctionnelle, plus lisible et élégante. Par exemple, je peux utiliser le corps de l'expression au lieu du corps entre crochets en enchaînant les "thens".
Mateus Felipe le
Il génère parfois une erreur lors de la compilation, vous devez utiliser des solutions natives. L'ajout de 'android: screenOrientation = "portrait"' à MainActivity sur AndroidManifest comme le suggère Abeer Iqbal a fonctionné pour moi sur Android.
Tincho825
Si vous rencontrez une erreur: «Exception non gérée: l'accès à ServicesBinding.defaultBinaryMessenger avant l'initialisation de la liaison». essayez d'utiliser ce correctif: stackoverflow.com/questions/57689492/…
Fillipe Silva
1

À partir des nouvelles versions de flutter avec le réglage du, preferred Orientationnous devons ajouter une ligne supplémentaire, c'est-à-dire

 WidgetsFlutterBinding.ensureInitialized();

Donc, le code de travail pour cela est -

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

Voici l'exemple officiel de l'équipe Flutter. 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
la source
0

Essayer

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

Vous pouvez également modifier les paramètres d'orientation de l'écran dans le fichier manifeste android et ios info.plist.

Bukunmi
la source
0

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

Ensuite, vous incluez la ligne de code ci-dessous dans votre fichier main.dart, et dans votre méthode principale comme ceci:

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

runApp(myApp());
Silas Ogar
la source
-4

La meilleure solution sera de l'utiliser dans la méthode de construction de MyApp ().

Aashar Wahla
la source