如何检测Flutter中布局的方向变化?

时间:2018-06-12 10:31:44

标签: dart orientation flutter flutter-layout

如何找出方向是Flutter中的纵向或横向

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

8 个答案:

答案 0 :(得分:19)

为了确定屏幕的方向,我们可以使用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,
    );
  },
);

你可以在这里找到完整的例子: this forum thread

答案 1 :(得分:11)

您可以使用MediaQuery检查方向:

MediaQuery.of(context).orientation == Orientation.portrait

答案 2 :(得分:4)

很容易

if (MediaQuery.of(context).orientation == Orientation.portrait){
    // is portrait
}else{
// is landscape
}

答案 3 :(得分:1)

OrientationBuilder(


 builder: (context, orientation) {
      return orientation == Orientation.portrait
          ? SafeArea(
          child: Scaffold(
              body: PortraitMode(context)
          )
      )
          : LandscapeMode(context);

    }
);

答案 4 :(得分:1)

出于完整性考虑,我想添加另一种方法来检测Flutter中的方向。答案中已经提到了两种检测方法。他们是

  1. 媒体查询
  2. 方向生成器

当我从Google工程师的“响应式设计video(跳至分钟2:34)学习Flutter时,遇到了第三种方法。它称为Layout Builder。这是简短的代码段:

return Padding(
    padding: _padding,
    child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
            if(constraints.maxHeight > constraints.maxWidth) {
                return _getPortraitLayout();
            }
            else {
                return _getLandscapeLayout();
            }
        },
    ),
);

答案 5 :(得分:0)

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: OrientationBuilder(builder: (_, orientation) {
      if (orientation == Orientation.portrait)
        return _buildPortraitLayout(); // if orientation is portrait, show your portrait layout
      else
        return _buildLandscapeLayout(); // else show the landscape one
    }),
  );
}

答案 6 :(得分:0)

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,
  ]);
}

答案 7 :(得分:0)

我的变种。

1) 在全局范围内设置 global 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,
                    );
                  },
                );