屏幕适配方案-flutter_screenutil

方木先生
分享互动规则

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 的设计稿还原,但复杂响应式布局仍然要配合 MediaQueryLayoutBuilderExpanded 等 Flutter 原生布局能力。

评论 0

支持 @用户名 提醒对方(需为站内已注册用户名);回复仅支持一层楼中楼。

登录后发表评论、回复与 @ 提及。

举报

举报会匿名发送给管理员审核。

  • 暂无评论,来发表第一条。

码谱 · The Digital Atelier · 技术内容社区