如何让Flutter应用的宽高适配不同屏幕尺寸?
Flutter 多屏幕尺寸适配及MediaQuery使用指南
你遇到的组件重叠、内容不可见问题本质是布局中使用了硬编码的固定尺寸值,没有根据运行设备的屏幕参数动态调整,MediaQuery是Flutter原生提供的获取设备屏幕全局参数的基础API,具体使用方法如下:
基础调用规则
MediaQuery需要在MaterialApp/CupertinoApp的子树中调用,否则会抛出空异常,基础调用语法为:final MediaQueryData mediaQuery = MediaQuery.of(context);
常用可获取的核心参数
- 屏幕逻辑宽度:
mediaQuery.size.width,返回值已自动适配设备像素比,无需额外换算 - 屏幕逻辑高度:
mediaQuery.size.height - 顶部状态栏高度:
mediaQuery.padding.top,可用于适配刘海屏、挖孔屏的顶部遮挡 - 底部安全区高度:
mediaQuery.padding.bottom,可避开iPhone HomeIndicator、安卓全面屏手势条的底部遮挡 - 系统文字缩放因子:
mediaQuery.textScaleFactor,用于适配用户调整系统字体大小的场景 - 设备像素比:
mediaQuery.devicePixelRatio,高清图片资源适配时可使用
实际适配场景示例
1. 动态组件尺寸适配
不要给组件硬编码固定宽高,改为基于屏幕比例设置:
// 原错误写法,小屏会溢出 Container(width: 300, child: ...) // 适配后写法,组件宽度始终占屏幕的80% Container(width: MediaQuery.of(context).size.width * 0.8, child: ...)
2. 安全区手动适配
如果页面未使用Scaffold自动处理安全区,可手动添加padding避开系统UI遮挡:
Padding( padding: EdgeInsets.only( top: MediaQuery.of(context).padding.top, bottom: MediaQuery.of(context).padding.bottom, ), child: 你的页面内容组件 )
3. 多设备断点适配
可基于屏幕宽度判断设备类型,返回不同的布局结构:
Widget build(BuildContext context) { final double screenWidth = MediaQuery.of(context).size.width; // 小屏手机(宽度<360逻辑像素) if (screenWidth < 360) { return 紧凑布局组件; // 普通手机(360≤宽度<600逻辑像素) } else if (screenWidth < 600) { return 常规布局组件; // 平板/横屏设备(宽度≥600逻辑像素) } else { return 适配平板的双列布局组件; } }
注意事项
- 不要在
initState生命周期中调用MediaQuery.of(context),此时context未完成挂载会抛出异常,建议在build方法或didChangeDependencies中调用 - 如果只需要获取单一参数,可使用专用方法减少不必要的组件重建,比如
MediaQuery.paddingOf(context)仅获取padding参数,性能优于获取完整的MediaQueryData - 文字大小适配建议配合
textScaleFactor使用,避免用户调大系统字体后文字溢出,示例:Text("展示内容", style: TextStyle(fontSize: 14 * MediaQuery.of(context).textScaleFactor))
内容的提问来源于stack exchange,提问作者Gokul Jayaraman
相关产品推荐
相关产品推荐

