Flutter中如何开发支持横竖屏双方向、旋转自动适配尺寸的应用
Flutter 竖屏/横屏双向自动适配开发实操
平台层基础权限配置
首先要打通系统层面的旋转限制,否则Flutter层的所有配置都不会生效:
- 安卓端:打开
android/app/src/main/AndroidManifest.xml,找到应用对应的<activity>节点,补充配置避免旋转时Activity被系统重建,配置内容为:
同时移除节点内默认的android:configChanges="orientation|screenSize|keyboardHidden|density"android:screenOrientation="portrait"竖屏锁配置,让系统可以正常响应旋转事件。 - iOS端:打开
ios/Runner/Info.plist,在UISupportedInterfaceOrientations数组中补充横屏方向的支持项,确保数组内同时包含竖屏、左横屏、右横屏三个方向的枚举值,不要只保留竖屏的单独配置。
Flutter 入口全局方向配置
在App启动的入口函数中,提前声明全应用允许响应的方向列表,必须在runApp执行前完成绑定:
void main() { // 必须先初始化组件绑定,否则调用SystemChrome相关API会抛出异常 WidgetsFlutterBinding.ensureInitialized(); // 配置所有允许响应的屏幕方向 SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, // 正竖屏 DeviceOrientation.portraitDown, // 倒竖屏 DeviceOrientation.landscapeLeft, // 左横屏 DeviceOrientation.landscapeRight, // 右横屏 ]); runApp(const MyApp()); }
注意:如果入口处只配置了竖屏方向,就算平台层放开了旋转权限,应用也不会响应设备的旋转事件。
页面布局的动态适配实现
完成基础配置后,屏幕旋转时Flutter会自动获取新的屏幕尺寸,只要避免给布局写死固定尺寸,就能实现旋转后的自动适配:
- 用实时尺寸计算替换固定尺寸配置:不要给跨方向的组件写死像素/逻辑像素的宽高,通过
MediaQuery获取实时屏幕宽高,判断当前是横屏还是竖屏状态,动态调整布局结构。比如横屏时把单列列表改成双列网格,竖屏时切回单列展示:final screenSize = MediaQuery.of(context).size; final isLandscape = screenSize.width > screenSize.height; return GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( // 横屏用2列布局,竖屏切回1列 crossAxisCount: isLandscape ? 2 : 1, // 动态调整子项宽高比,避免内容拉伸变形 childAspectRatio: isLandscape ? 3 : 1.5, ), itemCount: 30, itemBuilder: (context, index) => const Card(child: ListTile(title: Text("列表内容"))), ); - 用响应式组件替代手动方向判断:直接用
LayoutBuilder、OrientationBuilder组件包裹需要适配的页面,这类组件会在屏幕尺寸/方向变化时自动触发重建,不需要手动编写流监听旋转事件。比如横屏时隐藏默认AppBar实现沉浸式效果,竖屏时正常展示AppBar:OrientationBuilder( builder: (context, currentOrientation) { return Scaffold( appBar: currentOrientation == Orientation.landscape ? null : AppBar(title: const Text("页面标题")), body: /* 页面内容区域 */, ); }, ) - 避免旋转时出现布局溢出:所有会随屏幕尺寸变化的内容区域,都要包裹
SingleChildScrollView、Flexible、Expanded组件做弹性适配,不要给跨方向的布局节点写死固定高度/宽度,否则旋转时会出现布局溢出的黄色报错条纹。
灵活配置提示:如果不需要全局所有页面都支持横屏,可以在具体页面的生命周期中单独配置方向——比如视频播放页进入时单独设置允许横屏,退出时再恢复全局的竖屏锁定,不用在入口处给所有页面放开横屏权限。
内容的提问来源于stack exchange,提问作者Maheswari
相关产品推荐
相关产品推荐

