124 votes

Flutter : Comment définir et verrouiller l'orientation de l'écran à la demande

Sur l'une de mes pages flutter, j'ai besoin que l'écran soit en mode paysage et verrouillé afin qu'il ne puisse pas basculer en mode portrait, mais seulement sur cette page. J'ai donc besoin d'une façon d'activer cette fonction en temps réel. Quelqu'un sait-il comment faire?

Je voudrais qu'il tourne en mode paysage-gauche ou paysage-droit, mais pas en mode portrait.

231voto

Jus10 Points 1832

Tout d'abord, importez le package des services :

import 'package:flutter/services.dart';

Cela vous donnera accès à la classe SystemChrome, qui "contrôle des aspects spécifiques de l'interface graphique du système d'exploitation et de la manière dont elle interagit avec l'application."

Lorsque vous chargez le Widget, faites quelque chose comme ceci :

@override
void initState(){
  super.initState();
  SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
  ]);
}

puis lorsque je quitte la page, remettez-le à la normale comme ceci :

@override
dispose(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
  super.dispose();
}

2 votes

Mais semble fonctionner uniquement sur Android github.com/flutter/flutter/issues/20124

0 votes

Oh, je n'avais pas réalisé. C'est très possible, je n'ai testé cela que sur Android.

0 votes

Nevermind, cela peut être résolu par Platform Channel github.com/flutter/flutter/issues/13238#issuecomment-4359582‌​21 et je pense que cela sera bientôt corrigé.

36voto

kosiara Points 81

Je utiliserai un simple mixin pour verrouiller le téléphone en mode portrait. La solution suivante verrouille l'application entière en mode portrait ou définit des écrans spécifiques en mode portrait tout en permettant la rotation ailleurs.

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

/// Force le mode portrait uniquement dans toute l'application
/// Utilisez ce Mixin sur le widget d'application principal, par exemple app.dart
/// L''App' de Flutter doit étendre le Stateless widget.
///
/// Appelez `super.build(context)` dans la méthode build() principale
/// pour activer le mode portrait uniquement
mixin PortraitModeMixin on StatelessWidget {
  @override
  Widget build(BuildContext context) {
    _portraitModeOnly();
    return null;
  }
}

/// Force le mode portrait uniquement sur un écran spécifique
/// Utilisez ce Mixin sur l'écran spécifique que vous souhaitez
/// bloquer en mode portrait uniquement.
///
/// Appelez `super.build(context)` dans la méthode build() de l'état
/// et `super.dispose();` dans la méthode dispose() de l'état
mixin PortraitStatefulModeMixin on State {
  @override
  Widget build(BuildContext context) {
    _portraitModeOnly();
    return null;
  }

  @override
  void dispose() {
    _enableRotation();
  }
}

/// bloque la rotation; défini l'orientation en : portrait
void _portraitModeOnly() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
}

void _enableRotation() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
}

Pour bloquer la rotation dans toute l'application, implémentez PortraitModeMixin dans le widget App principal. N'oubliez pas d'appeler super.build(context) dans la méthode build(BuildContext context).

/// Widget App principal
class App extends StatelessWidget with PortraitModeMixin {
  const App();

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return CupertinoApp(
      title: 'Flutter Demo',
      theme: CupertinoThemeData(),
      home: Text("Exemple de blocage de rotation d'écran"),
    );
  }
}

Pour bloquer la rotation dans un écran spécifique, implémentez PortraitStatefulModeMixin dans l'état de l'écran spécifique. N'oubliez pas d'appeler super.build(context) dans la méthode build() de l'état et super.dispose() dans la méthode dispose(). Si votre écran est un StatelessWidget - répétez simplement la solution de l'App (exemple précédent) c'est-à-dire utilisez PortraitModeMixin.

/// Écran spécifique
class SampleScreen extends StatefulWidget {
  SampleScreen() : super();

  @override
  State createState() => _SampleScreenState();
}

class _SampleScreenState extends State
    with PortraitStatefulModeMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Text("Flutter - Exemple de blocage de rotation d'écran");
  }

  @override
  void dispose() {
     super.dispose();
  }
}

Les mixins avec une telle syntaxe fonctionnent à partir de Dart 2.1

2 votes

J'ai essayé votre classe mixin - la version Stateless fonctionne très bien, cependant la version Stateful lance une exception, une fois que ma classe Stateful appelle sa méthode dispose. Notez, j'appelle super.dispose() à l'intérieur de ma classe. Voici l'erreur: I/flutter (29686): L'assertion suivante a été levée lors de la finalisation de l'arborescence des widgets: I/flutter (29686): Échec de l'appel à super.dispose dans _MultiPlayerAcceptPageState.dispose. I/flutter (29686): Les implémentations de dispose() doivent toujours appeler la méthode dispose() de leur superclasse, pour s'assurer que toutes les I/flutter (29686): ressources utilisées par le widget sont correctement libérées.

1 votes

Même exception pour la version stateful. Avez-vous résolu ce problème?

1 votes

Résolu ! Si vous utilisez Android Studio, cela est clairement détectable. Il dit que dispose() est annoté comme @mustCallSuper. Cela signifie que vous devez ajouter super.dispose() à l'intérieur de la fonction de mixin elle-même.

15voto

Prusakov Points 167
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
    .then((_) {
      runApp(new MyApp());
    });
}

3 votes

Bien que ce code puisse fournir une solution à la question, il est préférable d'ajouter du contexte sur pourquoi/comment il fonctionne. Cela peut aider les futurs utilisateurs à apprendre et à appliquer ces connaissances à leur propre code. Vous êtes également susceptible de recevoir des retours positifs de la part des utilisateurs sous forme de votes en haut, lorsque le code est expliqué.

13voto

Chronoviser Points 61

Tout d'abord, verrouillez l'orientation de l'application en mode Portrait.

//Faites ceci dans main.dart
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
  .then((_) {
runApp(MyApp());
});

Deuxièmement, allez à l'écran spécifique où vous souhaitez changer l'orientation.

@override
void initState() {
super.initState();

SystemChrome.setPreferredOrientations([
  DeviceOrientation.portraitUp,
  DeviceOrientation.landscapeRight,
  DeviceOrientation.landscapeLeft
]);

}

@override
void dispose() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
_interstitialAd.dispose();
super.dispose();
}

Pour utiliser SystemChrome, vous devrez ajouter 'package:flutter/services.dart'

0 votes

Que faire en cas de widget sans état ?

0 votes

Vous avez besoin d'un widget stateful pour accéder aux méthodes du cycle de vie.

5voto

dev.zom Points 135

Parfois, cela peut ne pas fonctionner en raison d'informations nulles sur l'orientation. Vous pouvez l'utiliser simplement comme ceci:

import services.dart

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

// attendre l'orientation de l'écran de réglage après avoir initié l'application et -> puis verrouiller l'orientation

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