Flutter屏幕和字体适配(ScreenUtil)

一、简介

flutter_screenutil 是一个 Flutter 插件,专门用于处理屏幕适配问题。它简化了不同设备间尺寸差异的处理,确保你的应用在各种屏幕上都能保持良好的显示效果。开发者可以通过简单的调用来设置基于设计图尺寸的控件宽高和字体大小。

项目地址:https://github.com/OpenFlutter/flutter_screenutil.git

二、属性

属性 类型 默认值 描述
designSize Size Size(360,690) 设计稿中设备的尺寸(建议dp)
builder Widget Function() Container() 一般返回一个 MaterialApp 类型的 Function()
orientation Orientation portrait 屏幕方向
splitScreenMode bool true 支持分屏尺寸

三、使用方法

(1)添加依赖

在你的项目 pubspec.yaml 文件中添加 flutter_screenutil 依赖:

dependencies:

flutter_screenutil: ^5.9.3

然后执行 pub get 来下载并安装依赖。

(2)初始化

flutter_screenutil 提供了两种方式进行初始化:ScreenUtilInit 方式和 ScreenUtil.init 方式。首先在使用的地方导入包:

import 'package:flutter_screenutil/flutter_screenutil.dart';

ScreenUtilInit 方式

使用 ScreenUtilInit 方式进行初始化,需要将项目的 MaterialApp 进行一层包裹,然后在 builder 中返回项目本身的 MaterialApp ,在 ScreenUtilInit 的 designSize 参数中传入设计图的尺寸,实现如下:

Dart 复制代码
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: Size(360, 690), // 传入设计图尺寸
      builder: () => MaterialApp(
        ...
      ),
    );
  }
}

ScreenUtil.init 方式:

直接使用 ScreenUtil.init 方法,传入屏幕尺寸、设计图尺寸和屏幕方向即可对 flutter_screenutil 进行初始化,代码如下:

Dart 复制代码
ScreenUtil.init(
  BoxConstraints(
    maxWidth: MediaQuery.of(context).size.width,  //屏幕宽度
    maxHeight: MediaQuery.of(context).size.height, //屏幕高度
  ),
  designSize: const Size(360, 690), // 设计图尺寸
  orientation: Orientation.portrait); // 屏幕方向

使用这种方式只需在使用 flutter_screenutil 前进行初始化即可,一般放在根路由即第一个页面加载的时候进行初始化。

注意:ScreenUtil.init 不能在 MyApp 中进行初始化,会报如下错误 No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of(). This can happen because you have not added a WidgetsApp, CupertinoApp, or MaterialApp widget (those widgets introduce a MediaQuery), or it can happen if the context you use comes from a widget above those widgets. 因为这个时候还没加载 MaterialApp 无法使用 MediaQuery.of(context ) 获取到屏幕宽高

(3)使用

初始化以后就可以使用 flutter_screenutil 提供的方法获取到适配后的数值进行使用了。

可通过如下 api 获取宽高以及字体的适配数值:

Dart 复制代码
ScreenUtil().setWidth(540)  // 根据屏幕宽度适配尺寸
ScreenUtil().setHeight(200) // 根据屏幕高度适配尺寸(一般根据宽度适配即可)
ScreenUtil().radius(200)    // 根据宽度或高度中的较小者进行调整
ScreenUtil().setSp(24)      // 字体大小适配

传入的参数即为设计图上的大小。在实际使用中的示例如下:

Dart 复制代码
Container(
  width: ScreenUtil().setWidth(200),
  height: ScreenUtil().setHeight(540),
  child: Text("Hello", style: TextStyle(fontSize: ScreenUtil().setSp(24)),),
);

这样即可使用适配的数值进行开发.

但发现这样写太麻烦了,为了获取一个适配的数值,要写一串的很长的代码。flutter_screenutil 提供了更简洁的调用方法,使用 Dart 扩展为 num 类型扩展了一系列属性可以方便开发者调用,上面的 api 可以通过扩展属性进行如下转换:

Dart 复制代码
ScreenUtil().setWidth(540)  =>  540.h
ScreenUtil().setHeight(200) =>  200.w
ScreenUtil().radius(200)    =>  200.r
ScreenUtil().setSp(24)      =>  24.sp

修改后的使用示例如下:

Dart 复制代码
Container(
  width: 200.w,
  height: 540.h,
  child: Text("Hello", style: TextStyle(fontSize: 24.sp),),
);

四、字体适配

除了上面 4 种扩展属性以外,还提供了 sm 以及 sw、 sh

  • sm :取数值本身与 sp 的值最小的值,如 12.sm 则取 1212.sp 的值进行比较,取最小的值。

  • sw :screen width 的缩写,即屏幕宽度,作用是按屏幕宽度比例返回值。如 0.2.sw 则返回屏幕宽度的 20%,1.sw 则是整个屏幕宽度

  • sh :screen height 的缩写,及屏幕高度,作用与sw类似,返回指定比例的屏幕高度值。如 1.sh 为整个屏幕高度

使用 sp 作为字体单位,默认是会随着系统字体缩放进行变化,如果不想字体随着系统缩放而变化,可设置 textScaleFactor 为 1.0 来实现。

Dart 复制代码
// 示例代码:
Column(
	crossAxisAlignment: CrossAxisAlignment.start,
	children: <Widget>[
		Text(
			'我的文字大小在设计稿上是20dp,因为设置了`textScaleFactor`,所以不会随着系统的文字缩放比例变化',
      style: TextStyle(
      color: Colors.black,
      fontSize: 20.sp,
			),
			textScaleFactor: 1.0,
		),
		Text(
			'我的文字大小在设计稿上是20dp,会随着系统的文字缩放比例变化',
			style: TextStyle(
				color: Colors.black,
				fontSize: 20.sp,
			),
		),
	],
)

设置字体不随系统字体大小进行改变

项目中可对 MaterialApp 进行全局设置或者对 Text 进行单独设置:

全局设置:

Dart 复制代码
MaterialApp(
    debugShowCheckedModeBanner: false,
    title: 'Flutter_ScreenUtil',
    theme: ThemeData(
       primarySwatch: Colors.blue,
    ),
    builder: (context, widget) {
       return MediaQuery(
          ///设置文字大小不随系统设置改变
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
          child: widget,
       );
    },
    home: HomePage(title: 'FlutterScreenUtil Demo'),
),

Text 单独设置:

Dart 复制代码
Text("text", textScaleFactor: 1.0)

五、API 参考

Dart 复制代码
ScreenUtil().setWidth(540)  (sdk>=2.6 : 540.w)   // 根据屏幕宽度适配尺寸
ScreenUtil().setHeight(200) (sdk>=2.6 : 200.h)   // 根据屏幕高度适配尺寸(一般根据宽度适配即可)
ScreenUtil().radius(200)    (sdk>=2.6 : 200.r)   // 根据宽度或高度中的较小者进行调整
ScreenUtil().setSp(24)      (sdk>=2.6 : 24.sp)   // 适配字体

ScreenUtil.pixelRatio       // 设备的像素密度
ScreenUtil.screenWidth   (sdk>=2.6 : 1.sw)   // 设备宽度
ScreenUtil.screenHeight  (sdk>=2.6 : 1.sh)   // 设备高度
ScreenUtil.bottomBarHeight  // 底部安全区距离,适用于全面屏下面有按键的
ScreenUtil.statusBarHeight  // 状态栏高度 刘海屏会更高
ScreenUtil.textScaleFactor // 系统字体缩放比例

ScreenUtil().scaleWidth  // 实际宽度设计稿宽度的比例
ScreenUtil().scaleHeight // 实际高度与设计稿高度度的比例

ScreenUtil().orientation  // 屏幕方向

0.5.sw  // 屏幕宽度的0.5倍
0.5.sh  // 屏幕高度的50%
相关推荐
旧时光_25 分钟前
第5章:容器类组件 —— 5.1 填充(Padding)
flutter
renxhui30 分钟前
Flutter 基础控件速查(面向 Android 开发者)
flutter
A懿轩A42 分钟前
【2025版 OpenHarmony】 GitCode 口袋工具:Flutter + Dio 网路请求 打造随身的鸿蒙版 GitCode 搜索助手
windows·flutter·华为·鸿蒙·openharmony·开源鸿蒙
QuantumLeap丶1 小时前
《Flutter全栈开发实战指南:从零到高级》- 20 -主题与国际化
flutter·ios·前端框架
心随雨下1 小时前
Flutter动画系统详解
flutter
白茶三许1 小时前
【OpenHarmony】Flutter 本地存储全解析:从键值对到数据库
数据库·flutter·开源·openharmony·gitcode
晚霞的不甘3 小时前
Flutter 与开源鸿蒙(OpenHarmony)深度集成:从插件开发到分布式能力实战(续篇)
flutter·开源·harmonyos
晚霞的不甘3 小时前
Flutter 与开源鸿蒙(OpenHarmony)生态融合:从 UI 渲染到系统级能力调用的全链路开发范式
flutter·开源·harmonyos
嘴贱欠吻!3 小时前
开源鸿蒙-基于Flutter搭建GitCode口袋工具-2
flutter·华为·开源·harmonyos·gitcode
晚霞的不甘3 小时前
Flutter 与开源鸿蒙(OpenHarmony)扩展开发指南:自定义插件、系统能力封装与生态工具链建设
flutter·开源·harmonyos