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%
相关推荐
叽哥11 小时前
flutter学习第 14 节:动画与过渡效果
android·flutter·ios
想想肿子会怎么做14 小时前
Flutter 环境安装
前端·flutter
叽哥15 小时前
flutter学习第 13 节:本地存储
android·flutter·ios
来来走走1 天前
Flutter SharedPreferences存储数据基本使用
android·flutter
zeqinjie1 天前
回顾 24年 Flutter 骨架屏没有释放 CurvedAnimation 导致内存泄漏的血案
前端·flutter·ios
tangweiguo030519872 天前
Flutter Provider 状态管理全面解析与实战应用:从入门到精通
flutter
猪哥帅过吴彦祖2 天前
Flutter SizeTransition:让你的UI动画更加丝滑
android·flutter
张风捷特烈2 天前
鸿蒙纪·Flutter卷#02 | 已有 Flutter 项目鸿蒙化 · 3.27.4 版
android·flutter·harmonyos
TralyFang2 天前
Flutter 导致Positioned的不断重构问题
flutter