Flutter: як запобігти зміні орієнтації пристрою та примусити портрет?


123

Я хотів би запобігти моїй програмі змінити орієнтацію і змусити макет дотримуватися "портрета".

У main.dart я поставив:

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

але коли я використовую кнопки обертання Android Simulator, макет "слідує" за новою орієнтацією пристрою ...

Як я міг це вирішити?

Дякую


4
Якщо припустити, що ви імпортували 'package:flutter/services.dart', то, можливо, це помилка: github.com/flutter/flutter/isissue/13238
Брайан Кунг

Не впевнений, чому з вами це трапляється. Я спробував запустити ваш код на емуляторі, а також на власному пристрої, і він прекрасно працює.
Хемант Радж

SystemChrome.setPreferredOrientationsповертається асинхронно, тому здається, що runAppслід укласти в then.
Кен

Відповіді:


189

Імпорт package:flutter/services.dart, значить

Покладіть SystemChrome.setPreferredOrientationsвсередину Widget build()методу.

Приклад:

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

Оновлення

Це рішення може не працювати на деяких пристроях IOS, як це було зазначено в оновленій документації по флейтеру жовтня 2019 року.

Вони радять виправити орієнтацію, встановивши UISupportedInterfaceOrientations в Info.plist, як це

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

Для отримання додаткової інформації https://github.com/flutter/flutter/isissue/27235#issuecomment-508995063


Працювали. Дякую <3
Suthura Sudharaka

1
Якщо ви поставите SystemChrome.setPreferredOrientations в основному, ви отримаєте помилку: до доступу до ініціалізації прив'язки було доступно ServicesBinding.defaultBinaryMessenger. Вставлення коду в зборку працює, тому що прив'язки були ініціалізовані в цій точці.
Золотий лев

76

@boeledi. Якщо ви хочете "заблокувати" орієнтацію пристрою і не дати йому змінитись, коли користувач повертає телефон, це було легко встановлено як нижче,

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

Вам доведеться почекати, поки setPreferredOrientationsце завершиться, а потім запустити додаток

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

Іноді вона видає помилку під час компіляції, ви повинні використовувати власні рішення. Додавання 'android: screenOrientation = "portrait"' до MainActivity на AndroidManifest, як пропонують Abeer Iqbal, працюючи на мене на Android.
Tincho825

44

iOS:

Виклик SystemChrome.setPreferredOrientations()не працює для мене, і мені довелося змінити Device Orientationв проекті Xcode , як наступне:

введіть тут опис зображення

Android:

Встановіть screenOrientationатрибут portraitдля основної діяльності у файлі android/app/src/main/AndroidManifest.xmlтаким чином:

введіть тут опис зображення


У мене була така ж проблема, ти запустив її на iPad? Я протестував лише на iPad, і це, здається, є проблемою: github.com/flutter/flutter/isissue/27235
Хлопчик

android: Цей атрибут додано в API рівня 24
BloodLoss

Я використовую screenOrientationз рівня 8 API для Android. @BloodLoss, я думаю, ви читали це на документах, але про resizeableActivityатрибут. Перевірте посилання ще раз. ^^
Ерік М. Шпренгель

22

Метод 'setPreferredOrientations' повертає об’єкт Future. За документацією майбутнє представляє деяку цінність, яка буде доступна десь у майбутньому. Ось чому ви зачекаєте, поки це стане доступним, а потім перейдіть до програми. Отже, використовується метод "тоді", який, за визначенням, "реєструє зворотні дзвінки, які потрібно викликати, коли майбутнє завершиться". Отже, ви повинні використовувати цей код:

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

Також слід імпортувати такий файл:

'пакет: flutter / services.dart'


Я можу підтвердити це. Але використовуйте whenComplete () замість тоді (), коли функція не мала парам.
Csaba Gergely

20

Відкрийте android / app / src / main / AndroidManifest.xml та додайте наступний рядок у MainActivity:

android:screenOrientation="portrait"

Якщо у вас є це:

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

Ви повинні закінчити щось подібне:

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

Це працює для Android. На iOS вам доведеться змінити це зі сторінки Xcode: https://i.stack.imgur.com/hswoe.png (як сказав Хеджазі)


спасибі, ПАМ'ЯТИ порядок "портрета" після конфігурації Зміни "орієнтація" має значення.
MR_AMDEV

13

Перш за все імпортуйте це у файл main.dart

import 'package:flutter/services.dart';

Тоді не скопіюйте пасту, а перегляньте (запам'ятайте) і напишіть код нижче у файл main.dart

Щоб примусити в портретному режимі:

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

Для примусового використання в альбомному режимі:

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

1
Дякуємо за те, що нагадали людям не копіювати та не вставляти сліпо
Райан

1
Я бачу, чому ви попросили НЕ копіювати пасту ... закінчення} відсутнє ... Я копіюю вставлені ... :)
rohan koshti

не працював на хром, що летить
Золотий Лев

13

Помістіть WidgetsFlutterBinding.ensureInitialized () ще ви отримаєте помилку під час створення.

import 'package:flutter/services.dart';

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

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

          runApp(MainApp())
        };

5

setPreferredOrientationповертає a Future<void>, тож він є асинхронним. Найбільш читаний підхід - це визначити mainяк асинхронний:

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

3
Я категорично не згоден. awaitце всюдисущий шаблон програмування, який присутній на декількох мовах, і дуже зрозуміло, що виражає. thenстворює рівні гніздування. Якщо у вас три-чотири продовження, thenчитати по-справжньому стає дуже важко.
Роб Ліндон

.thenможна прикувати замість гніздування, як це очікує a FutureOr. Це дозволяє мені використовувати більш функціональний підхід, який є більш зрозумілим та елегантним. Наприклад, я можу використовувати тіло експресії замість скошеного тіла ланцюгом "тенів".
Матеус Феліпе

Іноді вона видає помилку під час компіляції, ви повинні використовувати власні рішення. Додавання 'android: screenOrientation = "portrait"' до MainActivity на AndroidManifest, як пропонують Abeer Iqbal, працюючи на мене на Android.
Tincho825

Якщо ви зіткнулися з помилкою: "Unhandled Exception: ServicesBinding.defaultBinaryMessenger був доступний до ініціалізації прив'язки." спробуйте використовувати це виправлення: stackoverflow.com/questions/57689492 / ...
Fillipe Silva

1

Щодо нових вершин флетера разом із встановленням preferred Orientationнам потрібно додати ще одну додаткову лінію, тобто

 WidgetsFlutterBinding.ensureInitialized();

Отже, робочий код для цього -

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

1

Нижче наводиться офіційний приклад колективу, що плаває. 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());
}

0

Спробуйте

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

Ви також можете змінити налаштування орієнтації екрана у файлі маніфесту Android та ios info.plist.


0

Імпорт імпорту 'пакет: flutter / services.dart';

Тоді ви включаєте рядок коду нижче у свій файл main.dart та в основний метод, наприклад:

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

runApp(myApp());

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.