flutter_screenutil 是 Flutter 里非常常用的屏幕适配插件,主要作用是:根据设计稿尺寸,把宽度、高度、字体、间距等 UI 尺寸自动换算到不同设备上,让页面在不同手机屏幕上看起来更接近设计稿。官方描述也是用于适配屏幕和字体大小,让 UI 在不同尺寸屏幕上有合理布局。(Dart packages)
一句话理解
假设设计稿是:
375 x 812
设计稿里按钮宽度是:
width: 100
如果你直接写死:
Container(width: 100)
在小屏、大屏、折叠屏、平板上视觉比例可能不一致。
用了 flutter_screenutil 后可以写:
Container(width: 100.w)
它会根据当前设备屏幕宽度自动缩放。
常见写法
1. 初始化
一般在 MaterialApp 外层包一层:
ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
splitScreenMode: true,
builder: (context, child) {
return MaterialApp(
home: child,
);
},
child: const HomePage(),
)
这里的核心是:
designSize: const Size(375, 812)
表示你的 UI 是按照 375 x 812 的设计稿来写的。
二、常用单位
1. .w:宽度适配
Container(
width: 100.w,
)
表示设计稿里的 100 宽度,会按当前设备宽度比例缩放。
常用于:
width
left / right padding
horizontal margin
2. .h:高度适配
Container(
height: 50.h,
)
表示设计稿里的 50 高度,会按当前设备高度比例缩放。
常用于:
height
top / bottom padding
vertical margin
3. .sp:字体适配
Text(
'Hello',
style: TextStyle(
fontSize: 16.sp,
),
)
表示字体大小根据屏幕进行适配。
常用于:
fontSize: 12.sp
fontSize: 14.sp
fontSize: 16.sp
4. .r:圆角 / 半径适配
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
),
)
常用于:
圆角
头像半径
图标尺寸
正方形组件
三、实际对比
不用 screenutil:
Container(
width: 100,
height: 44,
margin: const EdgeInsets.only(top: 20),
child: const Text(
'登录',
style: TextStyle(fontSize: 16),
),
)
使用 screenutil:
Container(
width: 100.w,
height: 44.h,
margin: EdgeInsets.only(top: 20.h),
child: Text(
'登录',
style: TextStyle(fontSize: 16.sp),
),
)
这样在不同设备上,UI 会更接近设计稿比例。
四、它解决什么问题?
主要解决这些问题:
设计稿是 375 宽,但真实手机有 360、390、414、430 等宽度
如果全部写死尺寸:
width: 300
height: 50
fontSize: 16
可能会出现:
小屏幕挤压
大屏幕显得太小
字体比例不协调
按钮、间距、圆角看起来不统一
flutter_screenutil 就是帮你把这些数值做比例换算。
五、在你的项目里一般怎么用?
结合你前面项目的资源配置,你的页面大概率会这样写:
Container(
width: 343.w,
height: 48.h,
padding: EdgeInsets.symmetric(horizontal: 16.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
),
child: Text(
'确认',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
),
),
)
图片也可以这样:
Image.asset(
'assets/images/images_login/logo.png',
width: 120.w,
height: 120.w,
)
注意这里如果图片是正方形,通常宽高都用 .w,这样不会因为宽高按不同方向缩放而变形。
六、.w、.h、.sp 怎么选?
| 场景 | 推荐 |
|---|---|
| 宽度 | .w |
| 高度 | .h |
| 左右间距 | .w |
| 上下间距 | .h |
| 字体 | .sp |
| 圆角 | .r |
| 图标尺寸 | .w 或 .r |
| 正方形图片 | 宽高都用 .w 或都用 .r |
例如:
SizedBox(width: 12.w)
SizedBox(height: 20.h)
TextStyle(fontSize: 14.sp)
BorderRadius.circular(8.r)
Icon(
Icons.home,
size: 24.w,
)
七、它不是万能的
flutter_screenutil 适合做“设计稿尺寸适配”,但不是所有响应式布局都应该靠它。
比如这种场景:
平板布局
横屏布局
折叠屏
Web 多栏布局
更推荐结合 Flutter 原生能力:
MediaQuery
LayoutBuilder
Expanded
Flexible
Wrap
GridView
FractionallySizedBox
简单理解:
screenutil:负责尺寸比例适配
LayoutBuilder / MediaQuery:负责布局结构适配
八、常见坑
1. 忘记初始化
如果没有包 ScreenUtilInit,直接使用:
100.w
16.sp
可能会出现适配异常或报错。
2. 设计稿尺寸写错
比如设计稿是 375 x 812,但你写成:
designSize: Size(360, 690)
那么所有 .w、.h、.sp 的缩放都会偏。
3. 全部地方都机械使用 .w / .h
不建议这样:
Container(
width: 1.sw,
height: 1.sh,
)
或者所有布局都强行定宽定高。
Flutter 本身是响应式布局,很多地方应该让组件自然撑开,而不是全部写死尺寸。
九、推荐使用方式
在业务项目里,我一般建议:
1. 字体用 sp
2. 左右间距用 w
3. 上下间距用 h
4. 圆角用 r
5. 图片、按钮、头像等设计稿固定尺寸可以用 w/h
6. 页面大结构不要过度依赖 screenutil,优先用 Flutter 弹性布局
一个比较规范的写法:
class LoginButton extends StatelessWidget {
const LoginButton({super.key});
@override
Widget build(BuildContext context) {
return Container(
height: 48.h,
margin: EdgeInsets.symmetric(horizontal: 16.w),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.blue,
),
child: Text(
'登录',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
);
}
}
总结
flutter_screenutil 的作用就是:
根据设计稿尺寸,自动适配不同手机屏幕下的宽、高、字体、圆角、间距等尺寸。
核心用法记住这几个就够了:
100.w // 宽度适配
50.h // 高度适配
16.sp // 字体适配
12.r // 圆角/半径适配
它适合移动端 App 的设计稿还原,但复杂响应式布局仍然要配合 MediaQuery、LayoutBuilder、Expanded 等 Flutter 原生布局能力。