【发布时间】:2026-01-05 20:20:03
【问题描述】:
方向更改处理是否像在 Flutter 中使用更新的尺寸重新运行小部件的构建一样简单?
我问是因为在 Android 中,整个 Activity 都会被重建,这就是为什么所有信息都通过 Intent 发送的原因。
在设计小部件时要记住哪些问题,以便它们处理方向更改或导致 UI 更改的其他更改?
【问题讨论】:
标签: flutter dart orientation
方向更改处理是否像在 Flutter 中使用更新的尺寸重新运行小部件的构建一样简单?
我问是因为在 Android 中,整个 Activity 都会被重建,这就是为什么所有信息都通过 Intent 发送的原因。
在设计小部件时要记住哪些问题,以便它们处理方向更改或导致 UI 更改的其他更改?
【问题讨论】:
标签: flutter dart orientation
基本上 - 是的!现在,更具体地说,MediaQuery 小部件侦听方向/大小/布局更改并重建它的子级。此小部件已经是 MaterialApp 和 WidgetsApp 小部件的一部分,因此您可能不需要包含它。
如果您希望您的小部件利用设备方向,您可以使用MediaQuery.of 静态成员来访问包含设备方向的MediaQueryData。例如,一个以纵向和横向显示不同文本的简单小部件(需要是 MaterialApp、WidgetsApp 或 MediaQuery 的子级)。
class MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
final mediaQueryData = MediaQuery.of(context);
if (mediaQueryData.orientation == Orientation.landscape) {
return const Text('landscape');
}
return const Text('portrait!');
}
}
【讨论】:
这将帮助您强制 Flutter 应用程序保持在纵向(垂直)模式,即使用户正在旋转智能手机
void main(){
///
/// Force the layout to Portrait mode
///
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
runApp(new MyApp());
}
【讨论】:
根据这个doc,你可以使用OrientationBuilder。
OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait)
// return A
else
// return B
});
【讨论】:
虽然上面 Jonah 的回答是正确的,但就我个人而言,我建议使用 switch 而不是 if。
需要在相关函数中实现不同的内容。
@override
Widget build(BuildContext context) {
switch (MediaQuery.of(context).orientation) {
case Orientation.landscape:
return _landscapeContent();
case Orientation.portrait:
default:
return _portraitContent();
}
}
更新
另一方面,当您有一个内部布尔值 _fullscreen 标志时,您保持全屏状态(假设您在某处有一个全屏按钮,并且即使手机处于纵向模式也希望显示该内容),然后if 会更方便。
@override
Widget build(BuildContext context) {
final orientation = MediaQuery.of(context).orientation;
if (orientation == Orientation.landscape || _fullscreen) {
return _landscapeContent();
}
return _portraitContent();
}
【讨论】:
要确定应用的当前Orientation,请使用OrientationBuilder 小部件。 OrientationBuilder 通过比较父小部件可用的宽度和高度来计算当前的Orientation,并在父窗口大小改变时重建。
使用Orientation,构建一个在纵向模式下显示两列或在横向模式下显示三列的列表。
OrientationBuilder(
builder: (context, orientation) {
return GridView.count(
// Create a grid with 2 columns in portrait mode,
// or 3 columns in landscape mode.
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
);
},
);
完整示例
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
const appTitle = 'Orientation Demo';
return const MaterialApp(
title: appTitle,
home: OrientationList(
title: appTitle,
),
);
}
}
class OrientationList extends StatelessWidget {
final String title;
const OrientationList({Key? key, required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: OrientationBuilder(
builder: (context, orientation) {
return GridView.count(
// Create a grid with 2 columns in portrait mode, or 3 columns in
// landscape mode.
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline1,
),
);
}),
);
},
),
);
}
}
【讨论】: