Как определить изменение ориентации макета во Flutter?

Как узнать ориентацию портретная или альбомная во Flutter

if(portrait){
  return ListView.builder()
}else{
  return GridView.count()
}

person Adarsh Vijayan P    schedule 12.06.2018    source источник


Ответы (7)


Чтобы определить ориентацию экрана, мы можем использовать виджет OrientationBuilder. OrientationBuilder определит текущую ориентацию и перестроит ее при изменении ориентации.

new OrientationBuilder(
  builder: (context, orientation) {
    return new GridView.count(
      // Create a grid with 2 columns in portrait mode, or 3 columns in
      // landscape mode.
      crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
    );
  },
);

вы можете найти полный пример здесь: https://flutter.io/cookbook/design/orientation/

person Siavash    schedule 12.06.2018

Вы можете использовать MediaQuery для проверки ориентации:

var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
person Günter Zöchbauer    schedule 12.06.2018
comment
@AdarshVijayanP вы не можете использовать это в случайных местах кода. Его следует использовать в build или didChangeDependencies - person Günter Zöchbauer; 12.06.2018
comment
@ GünterZöchbauer написал код на build, а затем передал его в мой виджет. Спасибо, теперь он отлично работает. - person Adarsh Vijayan P; 12.06.2018

это довольно просто

if (MediaQuery.of(context).orientation == Orientation.portrait){
    // is portrait
}else{
// is landscape
}
person Edgencio Da Calista    schedule 12.06.2018

Для полноты картины я хотел бы добавить еще один способ определения ориентации во Flutter. В ответах уже упоминались два способа обнаружения. Они есть

  1. Медиа-запрос
  2. Конструктор ориентации

Есть третий способ, с которым я столкнулся при изучении Flutter из видео (переходите к минуте 2:34) от инженеров Google. Это называется Layout Builder. Вот короткий фрагмент:

return Padding(
    padding: _padding,
    child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
            if(constraints.maxHeight > constraints.maxWidth) {
                return _getPortraitLayout();
            }
            else {
                return _getLandscapeLayout();
            }
        },
    ),
);
person user1506104    schedule 12.04.2020
comment
это работает, только если вы используете Layout Builder в неограниченном макете (например, в верхней части дерева виджетов экрана). Если вы поместите LayoutBuilder в контейнер с высотой = 50 и шириной = 100, ваш метод всегда будет сообщать пользователю, что он находится в ландшафтном режиме. - person Tiago Santos; 30.07.2020

Mediaquery нельзя использовать в initState(), а OrientationBuilder нужен виджет, поэтому я создал следующий класс, который можно использовать в любом месте проекта.

if(IsPortrait.isPortrait){
}else{
}

IsPortrait.class

class IsPortrait{
  static bool isPortrait = true;

  void init(BoxConstraints constraints, Orientation orientation) {
    if (orientation == Orientation.portrait) {
      isPortrait = true;
    }
   else{
     isPortrait = false;
   }
  }
}

следующие функции можно использовать для изменения ориентации

Только портретный режим

/// blocks rotation; sets orientation to: portrait
void _portraitModeOnly() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
}

Только альбомный режим

/// blocks rotation; sets orientation to: landscape
    void _landscapeModeOnly() {
      SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
      ]);
    }

Включить портретную ориентацию и пейзажный пейзаж

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

Мой вариант.

1) В глобальной области установите глобальный ValueNotifier:

final ValueNotifier<bool> IS_PORTRAIT = ValueNotifier<bool>(true);

2) В области действия скаффолда измените значение нашего глобального ValueNotifier

return Scaffold(
        key: scaffoldKey,
        body: OrientationBuilder(
          builder: (BuildContext context, Orientation orientation) {
            IS_PORTRAIT.value = orientation == Orientation.portrait;
            return MyBody();
          },
        ),
);

3) Где угодно слушать текущую ориентацию

return ValueListenableBuilder(
                  valueListenable: IS_PORTRAIT,
                  builder: (BuildContext context, value, Widget child) {
                     return Container(
                      color: Colors.green[100],
                      child: Container(),
                      height: (IS_PORTRAIT.value)? 150: 80,
                    );
                  },
                );
person Вячеслав Жалялетдинов    schedule 28.01.2021

person    schedule
comment
OrientationBuilder, похоже, работает только на уровне сборки. Когда я создаю виджет с отслеживанием состояния, это не работает дальше по дереву. Интересно, известно ли об этом. - person ChrisH; 26.03.2020