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%
相关推荐
星秋Eliot1 天前
认识 Flutter
flutter
tangweiguo030519871 天前
Flutter 根据后台配置动态生成页面完全指南
flutter
stringwu1 天前
Flutter开发者必备:状态管理Bloc的实用详解
前端·flutter
humiaor1 天前
Flutter之riverpod状态管理详解
flutter·provider·riverpod
浮生若茶80882 天前
创建Flutter项目的两种方式
flutter
RaidenLiu2 天前
Riverpod 3:组合与参数化的进阶实践
前端·flutter
ideal树叶2 天前
Provider中的watch、read、Consumer、ChangeNotifierProvider、ValueNotifierProvider
flutter
勤劳打代码2 天前
独辟蹊径 —— NSIS 自定义 EXE 应用名称
windows·flutter
阿笑带你学前端2 天前
当手机遇上电视:Flutter实现局域网遥控输入的奇妙之旅
前端·flutter
早起的年轻人2 天前
Flutter 3.35.2 以上版本中 数字转字符串的方法指南
前端·flutter