英文原文正文为项目原始 README(英文),本站后续会翻译为中文,当前仅剔除图片与无关章节并统一排版。
flutter_screenutil
一个用于适配屏幕和字体大小的 Flutter 插件。让你的 UI 在不同屏幕尺寸上显示合理的布局!
注意:该插件仍在开发中,某些 API 可能尚不可用。
使用
添加依赖
安装前请检查最新版本。如果新版本有任何问题,请使用之前的版本
dependencies:
flutter:
sdk: flutter
# add flutter_screenutil
flutter_screenutil: ^{latest version}
将以下导入添加到你的 Dart 代码中
import 'package:flutter_screenutil/flutter_screenutil.dart';
属性
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| designSize | 尺寸 | 尺寸(360,690) | 设计稿中设备屏幕的尺寸,单位为 dp |
| builder | 功能 | null | 返回使用库的属性的小部件(例如:MaterialApp 的主题) |
| child | 小部件 | null | builder 的一部分,其依赖项/属性不使用该库 |
| rebuildFactor | 函数 | default | 接收旧的和新的屏幕指标并返回在发生变化时是否需要重建的函数。 |
| splitScreenMode | 布尔值 | false | 支持分屏显示 |
| minTextAdapt | 布尔值 | false | 是否根据宽度和高度的最小值调整文本 |
| context | BuildContext | null | 如果未提供,则通过 MediaQuery.of(context) 获取物理设备数据 |
| fontSizeResolver | 函数 | default | 指定如何调整字体大小的函数。默认情况下字体大小随屏幕宽度缩放 |
| responsiveWidgets | 可迭代 |
null | 应包含在重建树中的小部件名称列表/集合(参见 如何标记小部件需要重建) |
| excludeWidgets | 可迭代 |
null | 应从重建树中排除的小部件名称列表/集合 |
| enableScaleWH | 函数 | null | 支持启用宽度和高度缩放 |
| enableScaleText | 函数 | null | 支持启用文本缩放 |
注意:你必须提供 builder、child 或两者都提供。
重建列表
从版本 5.9.0 开始,ScreenUtilInit 不会重建整个小部件树,而只会标记需要重建的小部件,前提是:
- 小部件不是 flutter 小部件(小部件可在 Flutter 文档 中查找)
- 小部件名称不以下划线(
_)开头 - 小部件未声明
SU混入 responsiveWidgets不包含小部件名称
如果你有一个使用该库的小部件且不符合这些条件,你可以添加 SU 混入或将小部件名称添加到 responsiveWidgets 列表中。
初始化并设置适合的尺寸和字体大小,以根据系统的“字体大小”辅助功能选项进行缩放
请在使用前设置设计稿的尺寸,即设计稿的宽度和高度。
第一种方法(您应该在应用中使用一次)
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
//Set the fit size (Find your UI design, look at the dimensions of the device screen and fill it in,unit in dp)
return ScreenUtilInit(
designSize: const Size(360, 690),
minTextAdapt: true,
splitScreenMode: true,
// Use builder only if you need to use library outside ScreenUtilInit context
builder: (_ , child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'First Method',
// You can use the library anywhere in the app even in theme
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp),
),
home: child,
);
},
child: const HomePage(title: 'First Method'),
);
}
}
第二种方法:你需要一个技巧来支持应用主题的 textTheme 中的字体适配
混合开发使用第二种方法
不支持这个:
MaterialApp(
...
//To support the following, you need to use the first initialization method
theme: ThemeData(
textTheme: TextTheme(
button: TextStyle(fontSize: 45.sp)
),
),
)
但是你可以这样做:
void main() async {
// Add this line
await ScreenUtil.ensureScreenSize();
runApp(MyApp());
}
...
MaterialApp(
...
builder: (ctx, child) {
ScreenUtil.init(ctx);
return Theme(
data: ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
),
child: HomePage(title: 'FlutterScreenUtil Demo'),
);
},
)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter_ScreenUtil',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(title: 'FlutterScreenUtil Demo'),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
//Set the fit size (fill in the screen size of the device in the design)
//If the design is based on the size of the 360*690(dp)
ScreenUtil.init(context, designSize: const Size(360, 690));
...
}
}
注意:第二次调用 ScreenUtil.init 时,任何未提供的参数将不会被替换为默认值。请改用 ScreenUtil.configure
应用程序接口
启用或禁用缩放
Widget build(BuildContext context) {
return ScreenUtilInit(
enableScaleWH: ()=>false,
enableScaleText: ()=>false,
//...
);
}
或
ScreenUtil.enableScale(enableWH: () => false, enableText: () => false);
传递设计稿的 dp 尺寸
ScreenUtil().setWidth(540) (dart sdk>=2.6 : 540.w) //Adapted to screen width
ScreenUtil().setHeight(200) (dart sdk>=2.6 : 200.h) //Adapted to screen height , under normal circumstances, the height still uses x.w
ScreenUtil().radius(200) (dart sdk>=2.6 : 200.r) //Adapt according to the smaller of width or height
ScreenUtil().setSp(24) (dart sdk>=2.6 : 24.sp) //Adapter font
12.sm //return min(12,12.sp)
ScreenUtil().pixelRatio //Device pixel density
ScreenUtil().screenWidth (dart sdk>=2.6 : 1.sw) //Device width
ScreenUtil().screenHeight (dart sdk>=2.6 : 1.sh) //Device height
ScreenUtil().bottomBarHeight //Bottom safe zone distance, suitable for buttons with full screen
ScreenUtil().statusBarHeight //Status bar height , Notch will be higher
ScreenUtil().textScaleFactor //System font scaling factor
ScreenUtil().scaleWidth //The ratio of actual width to UI design
ScreenUtil().scaleHeight //The ratio of actual height to UI design
ScreenUtil().orientation //Screen orientation
0.2.sw //0.2 times the screen width
0.5.sh //50% of screen height
20.setVerticalSpacing // SizedBox(height: 20 * scaleHeight)
20.horizontalSpace // SizedBox(height: 20 * scaleWidth)
const RPadding.all(8) // Padding.all(8.r) - take advantage of const key word
EdgeInsets.all(10).w //EdgeInsets.all(10.w)
REdgeInsets.all(8) // EdgeInsets.all(8.r)
EdgeInsets.only(left:8,right:8).r // EdgeInsets.only(left:8.r,right:8.r).
BoxConstraints(maxWidth: 100, minHeight: 100).w //BoxConstraints(maxWidth: 100.w, minHeight: 100.w)
Radius.circular(16).w //Radius.circular(16.w)
BorderRadius.all(Radius.circular(16)).w
适配屏幕尺寸
传入设计稿的 dp 尺寸(单位与初始化时相同):
适配屏幕宽度:ScreenUtil().setWidth(540),
适配屏幕高度:ScreenUtil().setHeight(200),一般情况下,高度最好适配宽度
如果你的 dart sdk >= 2.6,你可以使用扩展函数:
示例:
代替:
Container(
width: ScreenUtil().setWidth(50),
height:ScreenUtil().setHeight(200),
)
你可以这样使用它:
Container(
width: 50.w,
height:200.h
)
Note
高度也可以使用 setWidth 来确保不变形(当你想要一个正方形时)
setHeight 方法主要是为了适应高度,用于当你想在 UI 上控制屏幕高度与实际显示一致时。
一般来说,50.w != 50.h。
//for example:
//If you want to display a rectangle:
Container(
width: 375.w,
height: 375.h,
),
//If you want to display a square based on width:
Container(
width: 300.w,
height: 300.w,
),
//If you want to display a square based on height:
Container(
width: 300.h,
height: 300.h,
),
//If you want to display a square based on minimum(height, width):
Container(
width: 300.r,
height: 300.r,
),
适配器字体
//Incoming font size(The unit is the same as the unit at initialization)
ScreenUtil().setSp(28)
28.sp
//for example:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'16sp, will not change with the system.',
style: TextStyle(
color: Colors.black,
fontSize: 16.sp,
),
textScaleFactor: 1.0,
),
Text(
'16sp,if data is not set in MediaQuery,my font size will change with the system.',
style: TextStyle(
color: Colors.black,
fontSize: 16.sp,
),
),
],
)
设置字体不会随系统字体大小更改
APP 全局:
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter_ScreenUtil',
theme: ThemeData(
primarySwatch: Colors.blue,
),
builder: (context, widget) {
return MediaQuery(
///Setting font does not change with system font size
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: widget,
);
},
home: HomePage(title: 'FlutterScreenUtil Demo'),
),
指定文本:
Text("text", textScaleFactor: 1.0)
指定的组件:
MediaQuery(
// If there is no context available you can wrap [MediaQuery] with [Builder]
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: AnyWidget(),
)
示例
要使用第二种方法运行:flutter run --dart-define=method=2
效果
版本 5.9.0 更新(测试)
在 #515 中报告为错误
在版本 5.9.0 中,为确保测试的兼容性和正确运行,在进行依赖动画或需要完成状态的稳定时间的组件测试时,必须使用方法 tester.pumpAndSettle()。
在之前的版本中,这一步骤并不是严格必要的。然而,为了在测试中保持一致性并避免意外错误,如果您使用的是版本 5.9.0,强烈建议在您的小部件测试中加入 await tester.pumpAndSettle();
示例用法:
testWidgets('Should ensure widgets settle correctly', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: ScreenUtilInit(
child: MyApp(),
),
),
);
// Insertion of recommended method to prevent failures
await tester.pumpAndSettle();
// Continue with your assertions and tests
});- 本文标题:flutter_screenutil - Flutter 屏幕适配
- 本文链接:https://cn121.com/mobile/openflutter-flutter-screenutil.html
- 原项目:OpenFlutter/flutter_screenutil 版权归原作者 OpenFlutter 及贡献者所有
- 收录信息:本站于 2026-10-21 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
- 开源协议:收录时本项目采用 Apache-2.0(查看 LICENSE 原文),本站转载其原始文档(未改动文字,仅剔除图片与无关章节);使用、修改、分发请以该仓库 LICENSE 原文为准。本站对原文仅作排版与图片地址适配, 并保留原项目的 NOTICE 与署名要求。
- 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 OpenFlutter/flutter_screenutil。
- 内容说明:本页正文为原项目 README 原文(英文),本站后续会翻译为中文(当前尚未译出,仅将二级标题译为中文,便于按栏目定位;标题原文可在下方原仓库中查看),仅剔除了图片与赞助等无关章节、并把相对链接改为绝对地址;页首简介为机器翻译自仓库描述。
- 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
- 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。