277 votes

Flutter : comment empêcher les changements d'orientation de l'appareil et forcer le mode portrait ?

Je voudrais empêcher mon application de changer son orientation et forcer la disposition à rester en "portrait".

Dans le main.dart, j'ai ajouté:

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

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

Comment pourrais-je résoudre ce problème?

Merci

6 votes

En supposant que vous avez importé 'package:flutter/services.dart', alors peut-être que c'est un bug: github.com/flutter/flutter/issues/13238

0 votes

Pas certain pourquoi cela vous arrive. J'ai essayé d'exécuter votre code sur un émulateur ainsi que sur mon propre appareil et cela fonctionne correctement.

2 votes

SystemChrome.setPreferredOrientations retourne de manière asynchrone, donc il semble que runApp devrait être enveloppée dans un then.

350voto

Mason Points 1178

Importer package:flutter/services.dart, puis

Placez SystemChrome.setPreferredOrientations à l'intérieur de la méthode Widget build().

Exemple :

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

Mise à jour

Cette solution pourrait ne pas fonctionner pour certains appareils IOS comme mentionné dans la documentation Flutter mise à jour en octobre 2019.

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

    UIInterfaceOrientationPortrait

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

6 votes

Si vous placez SystemChrome.setPreferredOrientations dans le main, vous obtiendrez l'erreur : ServicesBinding.defaultBinaryMessenger a été accédé avant que la liaison ne soit initialisée. Insérer le code dans build fonctionne car les liaisons ont été initialisées à ce moment-là.

0 votes

Rappel que pour info.plist iOS, vous devez également le configurer pour iPad sous UISupportedInterfaceOrientations~ipad

0 votes

J'ai caché la barre des tâches Android avec SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]); et en ajoutant cela, elle réapparaît brièvement puis disparaît lorsque je touche quelque chose pour naviguer. Est-ce fait exprès ? J'ai le extrait de code ci-dessus imbriqué dans void initState() pour la page sur laquelle je veux cacher la barre des tâches Android et ton extrait de code dans le build de mon écran de niveau supérieur qui exécute main.

133voto

TejaDroid Points 3854

@boeledi, Si vous souhaitez "verrouiller" l'orientation de l'appareil et ne pas permettre qu'elle change lorsque l'utilisateur pivote son téléphone, cela peut être facilement configuré comme suit,

// Cela n'a pas fonctionné comme demandé
void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  runApp(new MyApp());
}

Vous devez attendre que setPreferredOrientations soit terminé avant de démarrer l'application

// Cela fonctionnera toujours pour verrouiller l'orientation de l'écran.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}

2 votes

Il arrive parfois qu'une erreur se produise lors de la compilation, vous devriez utiliser des solutions natives. Ajouter 'android:screenOrientation="portrait"' à MainActivity sur AndroidManifest comme le suggère Abeer Iqbal a fonctionné pour moi sur Android.

103voto

Hejazi Points 5981

iOS:

Appeler SystemChrome.setPreferredOrientations() ne fonctionne pas pour moi et j'ai dû changer l'Orientation de l'appareil dans le projet Xcode comme suit:

entrer la description de l'image ici

Android:

Définissez l'attribut screenOrientation sur portrait pour l'activité principale dans le fichier android/app/src/main/AndroidManifest.xml comme suit:

entrer la description de l'image ici

0 votes

J'ai rencontré 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

0 votes

Android: Cet attribut a été ajouté dans le niveau API 24.

1 votes

J'utilise screenOrientation depuis le niveau API 8 pour Android. @BloodLoss, je pense que tu l'as lu dans la documentation, mais à propos de l'attribut resizeableActivity. Vérifie à nouveau le lien. ^^

28voto

Ara Mkrtchyan Points 169

La méthode 'setPreferredOrientations' retourne un objet Future. Selon la documentation, un Future représente une valeur qui sera disponible quelque part dans le futur. C'est pourquoi vous devez attendre qu'elle soit disponible avant de continuer avec l'application. Par conséquent, vous devez utiliser la méthode 'then', qui, par définition, "enregistre des rappels à appeler lorsque le Future est terminé". Ainsi, vous devez utiliser ce code :

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

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

'package:flutter/services.dart'

0 votes

Je peux confirmer que cela fonctionne. Mais utilisez whenComplete() au lieu de then(), lorsque la fonction n'a pas de paramètre.

16voto

Pinkesh Darji Points 325

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

import 'package:flutter/services.dart';

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

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

2 votes

Merci de rappeler aux gens de ne pas copier-coller aveuglément.

3 votes

Je vois pourquoi vous avez demandé de ne pas copier-coller ... le } de fin est manquant... J'ai copié-collé... :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X