Flutter: come impedire le modifiche all'orientamento del dispositivo e forzare il ritratto?


124

Vorrei impedire alla mia applicazione di cambiare il suo orientamento e forzare il layout a restare "verticale".

Nel main.dart, ho messo:

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

ma quando utilizzo i pulsanti di rotazione del simulatore Android, il layout "segue" il nuovo orientamento del dispositivo ...

Come potrei risolverlo?

Grazie


4
Supponendo che tu abbia importato 'package:flutter/services.dart', forse è un bug: github.com/flutter/flutter/issues/13238
Brian Kung

Non sono sicuro del motivo per cui ti succede. Ho provato a eseguire il tuo codice su un emulatore e anche sul mio dispositivo e funziona bene.
Hemanth Raj

SystemChrome.setPreferredOrientationsrestituisce in modo asincrono, quindi sembra che runAppdovrebbe essere racchiuso in un then.
Ken il

Risposte:


193

Importa package:flutter/services.dart, quindi

Metti l' SystemChrome.setPreferredOrientationsinterno del Widget build()metodo.

Esempio:

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

Aggiornare

Questa soluzione potrebbe non funzionare per alcuni dispositivi IOS, come menzionato nella documentazione flutter aggiornata di ottobre 2019.

Consigliano di correggere l'orientamento impostando UISupportedInterfaceOrientations in Info.plist in questo modo

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

Per maggiori informazioni https://github.com/flutter/flutter/issues/27235#issuecomment-508995063


Lavorato. Grazie <3
Suthura Sudharaka

1
Se metti SystemChrome.setPreferredOrientations in main, otterrai l'errore: ServicesBinding.defaultBinaryMessenger è stato eseguito prima che l'associazione fosse inizializzata. L'inserimento del codice nella build funziona perché le associazioni sono state inizializzate a questo punto.
Leone d'oro il

77

@boeledi, se vuoi "bloccare" l'orientamento del dispositivo e non permettergli di cambiare mentre l'utente ruota il suo telefono, questo è stato facilmente impostato come di seguito,

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

Devi aspettare fino al setPreferredOrientationstermine e quindi avviare l'app

// This will works always for lock screen Orientation.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}

A volte genera un errore durante la compilazione, dovresti usare soluzioni native. L'aggiunta di 'android: screenOrientation = "portrait"' a MainActivity su AndroidManifest come suggerito da Abeer Iqbal ha funzionato per me su Android.
Tincho 825

44

iOS:

La chiamata SystemChrome.setPreferredOrientations()non funziona per me e ho dovuto modificare Device Orientationnel progetto Xcode come segue:

inserisci qui la descrizione dell'immagine

Android:

Impostare l' screenOrientationattributo su portraitper l'attività principale nel file android/app/src/main/AndroidManifest.xmlcome segue:

inserisci qui la descrizione dell'immagine


Ho avuto lo stesso problema, l'hai eseguito su un iPad? Ho provato solo su un iPad e questo sembra essere un problema: github.com/flutter/flutter/issues/27235
Boy

android: questo attributo è stato aggiunto nel livello API 24.
BloodLoss il

Uso screenOrientationdal livello API 8 per Android. @BloodLoss, penso che tu lo abbia letto sui documenti, ma sull'attributo resizeableActivity. Controlla di nuovo il collegamento. ^^
Erick M. Sprengel

22

Il metodo "setPreferredOrientations" restituisce un oggetto Future. Secondo la documentazione, un futuro rappresenta un valore che sarà disponibile da qualche parte in futuro. Ecco perché dovrai aspettare fino a quando non è disponibile e poi andare avanti con l'applicazione. Quindi, deve essere utilizzato il metodo "then", che, per definizione, "registra i callback da chiamare quando il futuro è completo". Quindi, utilizzerai questo codice:

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

Inoltre, è necessario importare il seguente file:

'pacchetto: flutter / services.dart'


Posso confermare che funziona. Ma usa whenComplete () invece di then (), quando la funzione non ha alcun parametro.
Csaba Gergely,

20

Apri android / app / src / main / AndroidManifest.xml e aggiungi la seguente riga in MainActivity:

android:screenOrientation="portrait"

Se hai questo:

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

Dovresti finire con qualcosa del genere:

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

Funziona per Android. Su iOS, dovrai modificarlo dalla pagina Xcode: https://i.stack.imgur.com/hswoe.png (come ha detto Hejazi)


grazie, RICORDA l'ordine di "ritratto" dopo l '"orientamento" di configChanges è importante.
MR_AMDEV

13

Prima di tutto importalo nel file main.dart

import 'package:flutter/services.dart';

Quindi non copiare e incollare piuttosto vedere (ricorda) e scrivere sotto il codice nel file main.dart

Per forzare in modalità verticale :

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

Per forzare in modalità orizzontale :

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

1
Grazie per aver ricordato alle persone di non copiare e incollare alla cieca
Ryan

1
Capisco perché hai chiesto di NON copiare incolla ... il finale} manca ... copia incollato ... :)
rohan koshti

non ha funzionato per flutter chrome
Golden Lion

13

Metti WidgetsFlutterBinding.ensureInitialized () altrimenti riceverai un errore durante la creazione.

import 'package:flutter/services.dart';

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

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

          runApp(MainApp())
        };

5

setPreferredOrientationrestituisce a Future<void>, quindi è asincrono. L'approccio più leggibile è definire maincome asincrono:

Future<void> main() async {
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  return runApp(new MyApp());
}

3
Sono fortemente in disaccordo. awaitè un modello di programmazione onnipresente che è presente in più linguaggi, ed è molto chiaro cosa sia espressivo. thencrea livelli di nidificazione. Se hai tre o quattro continuazioni, theninizia a diventare davvero molto difficile da leggere.
Rob Lyndon,

.thenpuò essere concatenato anziché annidato, come si aspetta a FutureOr. Ciò mi consente di utilizzare un approccio più funzionale, più leggibile ed elegante. Ad esempio, posso usare il corpo dell'espressione invece del corpo tra parentesi concatenando le "thens".
Mateus Felipe

A volte genera un errore durante la compilazione, dovresti usare soluzioni native. L'aggiunta di 'android: screenOrientation = "portrait"' a MainActivity su AndroidManifest come suggerito da Abeer Iqbal ha funzionato per me su Android.
Tincho 825

Se si verifica un errore: "Eccezione non gestita: è stato eseguito l'accesso a ServicesBinding.defaultBinaryMessenger prima che l'associazione fosse inizializzata." provare a utilizzare questa correzione: stackoverflow.com/questions/57689492/...
Fillipe Silva

1

A partire dalle nuove versioni di flutter insieme all'impostazione di preferred Orientationdobbiamo aggiungere una riga in più, ad es

 WidgetsFlutterBinding.ensureInitialized();

Quindi il codice funzionante per questo è -

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


0

Provare

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

Puoi anche modificare le impostazioni di orientamento dello schermo nel file manifest di Android e ios info.plist.


0

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

Quindi includi la riga di codice qui sotto nel tuo file main.dart e nel tuo metodo principale in questo modo:

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

runApp(myApp());

-4

La soluzione migliore sarà utilizzarlo nel metodo di compilazione di MyApp ().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.