如何检测 Flutter 中布局的方向变化?
How to detect orientation change in layout in Flutter?
如何在 Flutter 中判断 Orientation 是纵向还是横向
if(portrait){
return ListView.builder()
}else{
return GridView.count()
}
您可以使用 MediaQuery
检查方向:
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
为了确定屏幕的方向,我们可以使用 OrientationBuilder
小部件。 OrientationBuilder 会判断当前的 Orientation,当 Orientation 改变时重建。
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/
很简单
if (MediaQuery.of(context).orientation == Orientation.portrait){
// is portrait
}else{
// is landscape
}
@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
}),
);
}
OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? SafeArea(
child: Scaffold(
body: PortraitMode(context)
)
)
: LandscapeMode(context);
}
);
为了完整起见,我想添加另一种方法来检测 Flutter 中的方向。答案中已经提到了两种检测方法。他们是
- 媒体查询
- 方向生成器
我在从 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();
}
},
),
);
Mediaquery 不能在 initState()
中使用,OrientationBuilder 需要一个小部件,所以我创建了以下 class 可以在项目的任何地方使用。
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,
]);
}
我的变体。
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) Any where listen current orientation
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,
);
},
);
如何在 Flutter 中判断 Orientation 是纵向还是横向
if(portrait){
return ListView.builder()
}else{
return GridView.count()
}
您可以使用 MediaQuery
检查方向:
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
为了确定屏幕的方向,我们可以使用 OrientationBuilder
小部件。 OrientationBuilder 会判断当前的 Orientation,当 Orientation 改变时重建。
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/
很简单
if (MediaQuery.of(context).orientation == Orientation.portrait){
// is portrait
}else{
// is landscape
}
@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
}),
);
}
OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? SafeArea(
child: Scaffold(
body: PortraitMode(context)
)
)
: LandscapeMode(context);
}
);
为了完整起见,我想添加另一种方法来检测 Flutter 中的方向。答案中已经提到了两种检测方法。他们是
- 媒体查询
- 方向生成器
我在从 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();
}
},
),
);
Mediaquery 不能在 initState()
中使用,OrientationBuilder 需要一个小部件,所以我创建了以下 class 可以在项目的任何地方使用。
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,
]);
}
我的变体。
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) Any where listen current orientation
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,
);
},
);