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


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


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

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


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'


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)


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

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

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

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


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.


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

-4

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.