Mounir Bouaiche
Committed by GitHub

Fix initializing with Size(0, 0). closes #350, closes #348, closes #347 (#352)

* Fix initializing with Size(0, 0)

Only in Production Mode, Flutter starts quicker and the native platform reports the actual resolution in a certain delai. This update only wait for the real resolution.

* Upgrade to latest gradle version and enable Jetifier and use AndroidX

* Update example flutter version

* Optimize BugFix and some boilerplate removal

* Update example app

* Fix creating adaptive radius using extension

* Update example/ios/.gitignore

* Update README.md

* Update screenutil_init.dart
1 # flutter_screenutil 1 # flutter_screenutil
  2 +
2 [![pub package](https://img.shields.io/pub/v/flutter_screenutil.svg)](https://pub.dev/packages/flutter_screenutil) 3 [![pub package](https://img.shields.io/pub/v/flutter_screenutil.svg)](https://pub.dev/packages/flutter_screenutil)
3 [![pub points](https://badges.bar/flutter_screenutil/pub%20points)](https://pub.dev/packages/flutter_screenutil/score) 4 [![pub points](https://badges.bar/flutter_screenutil/pub%20points)](https://pub.dev/packages/flutter_screenutil/score)
4 [![popularity](https://badges.bar/flutter_screenutil/popularity)](https://pub.dev/packages/flutter_screenutil/score) 5 [![popularity](https://badges.bar/flutter_screenutil/popularity)](https://pub.dev/packages/flutter_screenutil/score)
@@ -15,11 +16,13 @@ @@ -15,11 +16,13 @@
15 16
16 [Update log](https://github.com/OpenFlutter/flutter_screenutil/blob/master/CHANGELOG.md) 17 [Update log](https://github.com/OpenFlutter/flutter_screenutil/blob/master/CHANGELOG.md)
17 18
18 -## Usage: 19 +## Usage
  20 +
  21 +### Add dependency
19 22
20 -### Add dependency:  
21 Please check the latest version before installation. 23 Please check the latest version before installation.
22 If there is any problem with the new version, please use the previous version 24 If there is any problem with the new version, please use the previous version
  25 +
23 ```yaml 26 ```yaml
24 dependencies: 27 dependencies:
25 flutter: 28 flutter:
@@ -27,61 +30,31 @@ dependencies: @@ -27,61 +30,31 @@ dependencies:
27 # add flutter_screenutil 30 # add flutter_screenutil
28 flutter_screenutil: ^{latest version} 31 flutter_screenutil: ^{latest version}
29 ``` 32 ```
30 -### Add the following imports to your Dart code: 33 +
  34 +### Add the following imports to your Dart code
  35 +
31 ```dart 36 ```dart
32 import 'package:flutter_screenutil/flutter_screenutil.dart'; 37 import 'package:flutter_screenutil/flutter_screenutil.dart';
33 ``` 38 ```
34 39
35 ### Property 40 ### Property
36 -<table style="width:100%">  
37 - <tr>  
38 - <th>Property</th>  
39 - <th>Type</th>  
40 - <th>Default Value</th>  
41 - <th>Description</th>  
42 - </tr>  
43 - <tr>  
44 - <td>designSize</td>  
45 - <td>Size</td>  
46 - <td>Size(360, 690)</td>  
47 - <td>The size of the device screen in the design draft, in dp</td>  
48 - </tr>  
49 - <tr>  
50 - <td>builder</td>  
51 - <td>Widget Function()</td>  
52 - <td>Container()</td>  
53 - <td>Generally returning a Function of MaterialApp type</td>  
54 - </tr>  
55 - <tr>  
56 - <td>orientation</td>  
57 - <td>Orientation</td>  
58 - <td>portrait</td>  
59 - <td>screen orientation</td>  
60 - </tr>  
61 - <tr>  
62 - <td>splitScreenMode</td>  
63 - <td>bool</td>  
64 - <td>true</td>  
65 - <td>support for split screen</td>  
66 - </tr>  
67 - <tr>  
68 - <td>minTextAdapt</td>  
69 - <td>bool</td>  
70 - <td>false</td>  
71 - <td>Whether to adapt the text according to the minimum of width and height</td>  
72 - </tr>  
73 - <tr>  
74 - <td>context</td>  
75 - <td>BuildContext</td>  
76 - <td>null</td>  
77 - <td>If context!=null, screen changes will be more sensitive</td>  
78 - </tr>  
79 -</table>  
80 -  
81 -### Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option 41 +
  42 +| Property | Type | Default Value | Description |
  43 +| --------------- | ------------- | -------------- | ---------------------------------------------------------------------- |
  44 +| deviceSize | Size | null | The size of the physical device |
  45 +| designSize | Size | Size(360, 690) | The size of the device screen in the design draft, in dp |
  46 +| builder | WidgetBuilder | (*required*) | Generally returning a Function of MaterialApp type |
  47 +| orientation | Orientation | portrait | screen orientation |
  48 +| splitScreenMode | bool | true | support for split screen |
  49 +| minTextAdapt | bool | false | Whether to adapt the text according to the minimum of width and height |
  50 +| context | BuildContext | null | Get physical device data if not provided, by MediaQuery.of(context) |
  51 +
  52 +### Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option |
  53 +
82 Please set the size of the design draft before use, the width and height of the design draft. 54 Please set the size of the design draft before use, the width and height of the design draft.
83 55
84 -#### The first way: 56 +#### The first way
  57 +
85 ```dart 58 ```dart
86 void main() => runApp(MyApp()); 59 void main() => runApp(MyApp());
87 60
@@ -93,47 +66,69 @@ class MyApp extends StatelessWidget { @@ -93,47 +66,69 @@ class MyApp extends StatelessWidget {
93 designSize: Size(360, 690), 66 designSize: Size(360, 690),
94 minTextAdapt: true, 67 minTextAdapt: true,
95 splitScreenMode: true, 68 splitScreenMode: true,
96 - builder: () =>  
97 - MaterialApp(  
98 - //... other code  
99 - builder: (context, widget) {  
100 - //add this line  
101 - ScreenUtil.setContext(context);  
102 - return MediaQuery(  
103 - //Setting font does not change with system font size  
104 - data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),  
105 - child: widget!,  
106 - );  
107 - }, 69 + builder: (_) {
  70 + return MaterialApp(
  71 + debugShowCheckedModeBanner: false,
  72 + // Use this line to prevent extra rebuilds
  73 + useInheritedMediaQuery: true,
  74 + title: 'First Method',
  75 + // You can use the library anywhere in the app even in theme
108 theme: ThemeData( 76 theme: ThemeData(
109 - textTheme: TextTheme(  
110 - //To support the following, you need to use the first initialization method  
111 - button: TextStyle(fontSize: 45.sp)  
112 - ),  
113 - ), 77 + primarySwatch: Colors.blue,
  78 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
114 ), 79 ),
  80 + home: HomePage(title: 'First Method'),
  81 + );
  82 + },
115 ); 83 );
116 } 84 }
117 } 85 }
118 86
119 ``` 87 ```
120 -#### The second way:Does not support font adaptation in the textTheme of MaterialApp's theme. 88 +
  89 +#### The second way:You need a trick to support font adaptation in the textTheme of app theme
  90 +
121 **Hybrid development uses the second way** 91 **Hybrid development uses the second way**
122 **(If it is not necessary, it is recommended to use the second)** 92 **(If it is not necessary, it is recommended to use the second)**
123 93
124 not support this: 94 not support this:
  95 +
125 ```dart 96 ```dart
126 MaterialApp( 97 MaterialApp(
127 ... 98 ...
  99 + //To support the following, you need to use the first initialization method
128 theme: ThemeData( 100 theme: ThemeData(
129 textTheme: TextTheme( 101 textTheme: TextTheme(
130 - //To support the following, you need to use the first initialization method  
131 button: TextStyle(fontSize: 45.sp) 102 button: TextStyle(fontSize: 45.sp)
132 ), 103 ),
133 ), 104 ),
134 ) 105 )
135 ``` 106 ```
136 107
  108 +but you can do this:
  109 +
  110 +```dart
  111 +void main() async {
  112 + // Add this line
  113 + await ScreenUtil.ensureScreenSize();
  114 + runApp(MyApp());
  115 +}
  116 +...
  117 +MaterialApp(
  118 + ...
  119 + builder: (ctx, child) {
  120 + ScreenUtil.init(ctx);
  121 + return Theme(
  122 + data: ThemeData(
  123 + primarySwatch: Colors.blue,
  124 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
  125 + ),
  126 + child: HomePage(title: 'FlutterScreenUtil Demo'),
  127 + );
  128 + },
  129 +)
  130 +```
  131 +
137 ```dart 132 ```dart
138 class MyApp extends StatelessWidget { 133 class MyApp extends StatelessWidget {
139 @override 134 @override
@@ -161,22 +156,14 @@ class HomePage extends StatefulWidget { @@ -161,22 +156,14 @@ class HomePage extends StatefulWidget {
161 class _HomePageState extends State<HomePage> { 156 class _HomePageState extends State<HomePage> {
162 @override 157 @override
163 Widget build(BuildContext context) { 158 Widget build(BuildContext context) {
164 - //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)  
165 - ScreenUtil.init(  
166 - BoxConstraints(  
167 - maxWidth: MediaQuery.of(context).size.width,  
168 - maxHeight: MediaQuery.of(context).size.height),  
169 - designSize: Size(360, 690),  
170 - context: context,  
171 - minTextAdapt: true,  
172 - orientation: Orientation.portrait);  
173 - return Scaffold(); 159 + //Set the fit size (fill in the screen size of the device in the design)
  160 + //If the design is based on the size of the 360*690(dp)
  161 + ScreenUtil.init(context, designSize: const Size(360, 690));
  162 + ...
174 } 163 }
175 } 164 }
176 ``` 165 ```
177 166
178 -### Use:  
179 -  
180 ### API 167 ### API
181 168
182 #### Pass the dp size of the design draft 169 #### Pass the dp size of the design draft
@@ -208,7 +195,7 @@ class _HomePageState extends State<HomePage> { @@ -208,7 +195,7 @@ class _HomePageState extends State<HomePage> {
208 EdgeInsets.only(left:8,right:8).r // EdgeInsets.only(left:8.r,right:8.r). 195 EdgeInsets.only(left:8,right:8).r // EdgeInsets.only(left:8.r,right:8.r).
209 ``` 196 ```
210 197
211 -#### Adapt screen size 198 +#### Adapt screen size
212 199
213 Pass the dp size of the design draft((The unit is the same as the unit at initialization)): 200 Pass the dp size of the design draft((The unit is the same as the unit at initialization)):
214 201
@@ -221,20 +208,24 @@ If your dart sdk>=2.6, you can use extension functions: @@ -221,20 +208,24 @@ If your dart sdk>=2.6, you can use extension functions:
221 example: 208 example:
222 209
223 instead of : 210 instead of :
  211 +
224 ```dart 212 ```dart
225 Container( 213 Container(
226 -width: ScreenUtil().setWidth(50),  
227 -height:ScreenUtil().setHeight(200), 214 + width: ScreenUtil().setWidth(50),
  215 + height:ScreenUtil().setHeight(200),
228 ) 216 )
229 ``` 217 ```
  218 +
230 you can use it like this: 219 you can use it like this:
  220 +
231 ```dart 221 ```dart
232 Container( 222 Container(
233 -width: 50.w,  
234 -height:200.h 223 + width: 50.w,
  224 + height:200.h
235 ) 225 )
236 ``` 226 ```
237 -**Note** 227 +
  228 +#### `Note`
238 229
239 The height can also use setWidth to ensure that it is not deformed(when you want a square) 230 The height can also use setWidth to ensure that it is not deformed(when you want a square)
240 231
@@ -245,29 +236,33 @@ Generally speaking, 50.w!=50.h. @@ -245,29 +236,33 @@ Generally speaking, 50.w!=50.h.
245 ```dart 236 ```dart
246 //for example: 237 //for example:
247 238
248 -///If you want to display a square:  
249 -///The UI may show a rectangle: 239 +//If you want to display a rectangle:
250 Container( 240 Container(
251 width: 375.w, 241 width: 375.w,
252 height: 375.h, 242 height: 375.h,
253 - ), 243 +),
254 244
255 -////If you want to display a square: 245 +//If you want to display a square based on width:
256 Container( 246 Container(
257 width: 300.w, 247 width: 300.w,
258 height: 300.w, 248 height: 300.w,
259 - ), 249 +),
260 250
261 -or 251 +//If you want to display a square based on height:
  252 +Container(
  253 + width: 300.h,
  254 + height: 300.h,
  255 +),
262 256
  257 +//If you want to display a square based on minimum(height, width):
263 Container( 258 Container(
264 width: 300.r, 259 width: 300.r,
265 height: 300.r, 260 height: 300.r,
266 - ), 261 +),
267 ``` 262 ```
268 263
  264 +#### Adapter font
269 265
270 -#### Adapter font:  
271 ``` dart 266 ``` dart
272 //Incoming font size(The unit is the same as the unit at initialization) 267 //Incoming font size(The unit is the same as the unit at initialization)
273 ScreenUtil().setSp(28) 268 ScreenUtil().setSp(28)
@@ -293,14 +288,15 @@ Column( @@ -293,14 +288,15 @@ Column(
293 ), 288 ),
294 ), 289 ),
295 ], 290 ],
296 - ) 291 +)
297 ``` 292 ```
298 293
299 #### Setting font does not change with system font size 294 #### Setting font does not change with system font size
300 295
301 APP global: 296 APP global:
  297 +
302 ```dart 298 ```dart
303 - MaterialApp( 299 +MaterialApp(
304 debugShowCheckedModeBanner: false, 300 debugShowCheckedModeBanner: false,
305 title: 'Flutter_ScreenUtil', 301 title: 'Flutter_ScreenUtil',
306 theme: ThemeData( 302 theme: ThemeData(
@@ -314,21 +310,34 @@ APP global: @@ -314,21 +310,34 @@ APP global:
314 ); 310 );
315 }, 311 },
316 home: HomePage(title: 'FlutterScreenUtil Demo'), 312 home: HomePage(title: 'FlutterScreenUtil Demo'),
317 - ), 313 +),
318 ``` 314 ```
319 315
320 -Separate Text: 316 +Specified Text:
  317 +
321 ```dart 318 ```dart
322 Text("text", textScaleFactor: 1.0) 319 Text("text", textScaleFactor: 1.0)
323 ``` 320 ```
324 321
  322 +Specified Widget:
  323 +
  324 +```dart
  325 +MediaQuery(
  326 + // If there is no context available you can wrap [MediaQuery] with [Builder]
  327 + data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
  328 + child: AnyWidget(),
  329 +)
  330 +```
  331 +
325 [widget test](https://github.com/OpenFlutter/flutter_screenutil/issues/115) 332 [widget test](https://github.com/OpenFlutter/flutter_screenutil/issues/115)
326 333
327 -### Example: 334 +### Example
  335 +
  336 +[example demo](https://github.com/OpenFlutter/flutter_screenutil/blob/master/example/lib)
328 337
329 -[example demo](https://github.com/OpenFlutter/flutter_screenutil/blob/master/example/lib/main.dart) 338 +To use second method run: `flutter run --dart-define=method=2`
330 339
331 -### Effect: 340 +### Effect
332 341
333 ![effect](demo_en.png) 342 ![effect](demo_en.png)
334 ![tablet effect](demo_tablet_en.png) 343 ![tablet effect](demo_tablet_en.png)
@@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
26 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 27
28 android { 28 android {
29 - compileSdkVersion 28 29 + compileSdkVersion 31
30 30
31 sourceSets { 31 sourceSets {
32 main.java.srcDirs += 'src/main/kotlin' 32 main.java.srcDirs += 'src/main/kotlin'
@@ -40,7 +40,7 @@ android { @@ -40,7 +40,7 @@ android {
40 // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 40 // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 applicationId "li.zhuoyuan.example" 41 applicationId "li.zhuoyuan.example"
42 minSdkVersion 16 42 minSdkVersion 16
43 - targetSdkVersion 28 43 + targetSdkVersion 31
44 versionCode flutterVersionCode.toInteger() 44 versionCode flutterVersionCode.toInteger()
45 versionName flutterVersionName 45 versionName flutterVersionName
46 } 46 }
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 <activity 12 <activity
13 android:name=".MainActivity" 13 android:name=".MainActivity"
14 android:launchMode="singleTop" 14 android:launchMode="singleTop"
  15 + android:exported="true"
15 android:theme="@style/LaunchTheme" 16 android:theme="@style/LaunchTheme"
16 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" 17 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
17 android:hardwareAccelerated="true" 18 android:hardwareAccelerated="true"
@@ -23,14 +24,6 @@ @@ -23,14 +24,6 @@
23 <meta-data 24 <meta-data
24 android:name="io.flutter.embedding.android.NormalTheme" 25 android:name="io.flutter.embedding.android.NormalTheme"
25 android:resource="@style/NormalTheme" /> 26 android:resource="@style/NormalTheme" />
26 - <!-- Displays an Android View that continues showing the launch screen  
27 - Drawable until Flutter paints its first frame, then this splash  
28 - screen fades out. A splash screen is useful to avoid any visual  
29 - gap between the end of Android's launch screen and the painting of  
30 - Flutter's first frame. -->  
31 - <meta-data  
32 - android:name="io.flutter.embedding.android.SplashScreenDrawable"  
33 - android:resource="@drawable/launch_background" />  
34 <intent-filter> 27 <intent-filter>
35 <action android:name="android.intent.action.MAIN" /> 28 <action android:name="android.intent.action.MAIN" />
36 <category android:name="android.intent.category.LAUNCHER" /> 29 <category android:name="android.intent.category.LAUNCHER" />
@@ -6,7 +6,7 @@ buildscript { @@ -6,7 +6,7 @@ buildscript {
6 } 6 }
7 7
8 dependencies { 8 dependencies {
9 - classpath 'com.android.tools.build:gradle:3.5.0' 9 + classpath 'com.android.tools.build:gradle:7.1.2'
10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 } 11 }
12 } 12 }
  1 +org.gradle.jvmargs=-Xmx1536M
  2 +android.useAndroidX=true
  3 +android.enableJetifier=true
  1 +#Fri Jun 23 08:50:38 CEST 2017
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionPath=wrapper/dists
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
  6 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
1 -.idea/  
2 -.vagrant/  
3 -.sconsign.dblite  
4 -.svn/  
5 -  
6 -.DS_Store  
7 -*.swp  
8 -profile  
9 -  
10 -DerivedData/  
11 -build/  
12 -GeneratedPluginRegistrant.h  
13 -GeneratedPluginRegistrant.m  
14 -  
15 -.generated/  
16 -  
17 -*.pbxuser 1 +**/dgph
18 *.mode1v3 2 *.mode1v3
19 *.mode2v3 3 *.mode2v3
  4 +*.moved-aside
  5 +*.pbxuser
20 *.perspectivev3 6 *.perspectivev3
21 -  
22 -!default.pbxuser 7 +**/*sync/
  8 +.sconsign.dblite
  9 +.tags*
  10 +**/.vagrant/
  11 +**/DerivedData/
  12 +Icon?
  13 +**/Pods/
  14 +**/.symlinks/
  15 +profile
  16 +xcuserdata
  17 +**/.generated/
  18 +Flutter/App.framework
  19 +Flutter/Flutter.framework
  20 +Flutter/Flutter.podspec
  21 +Flutter/Generated.xcconfig
  22 +Flutter/ephemeral/
  23 +Flutter/app.flx
  24 +Flutter/app.zip
  25 +Flutter/flutter_assets/
  26 +Flutter/flutter_export_environment.sh
  27 +ServiceDefinitions.json
  28 +Runner/GeneratedPluginRegistrant.*
  29 +
  30 +# Exceptions to above rules.
23 !default.mode1v3 31 !default.mode1v3
24 !default.mode2v3 32 !default.mode2v3
  33 +!default.pbxuser
25 !default.perspectivev3 34 !default.perspectivev3
26 -  
27 -xcuserdata  
28 -  
29 -*.moved-aside  
30 -  
31 -*.pyc  
32 -*sync/  
33 -Icon?  
34 -.tags*  
35 -  
36 -/Flutter/app.flx  
37 -/Flutter/app.zip  
38 -/Flutter/flutter_assets/  
39 -/Flutter/App.framework  
40 -/Flutter/Flutter.framework  
41 -/Flutter/Generated.xcconfig  
42 -/ServiceDefinitions.json  
43 -  
44 -Pods/  
45 -.symlinks/  
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter/services.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart'; 1 +import 'package:flutter/widgets.dart';
  2 +import 'src/first_method.dart' as firstMethod;
  3 +import 'src/second_method.dart' as secondMethod;
4 4
5 void main() { 5 void main() {
6 - runApp(MyApp());  
7 -}  
8 -  
9 -class MyApp extends StatelessWidget {  
10 - @override  
11 - Widget build(BuildContext context) {  
12 - //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 iPhone6 ​​(iPhone6 ​​750*1334)  
13 - return ScreenUtilInit(  
14 - designSize: Size(360, 690),  
15 - minTextAdapt: true,  
16 - splitScreenMode: true,  
17 - builder: () => MaterialApp(  
18 - debugShowCheckedModeBanner: false,  
19 - title: 'Flutter_ScreenUtil',  
20 - theme: ThemeData(  
21 - primarySwatch: Colors.blue,  
22 - textTheme: TextTheme(button: TextStyle(fontSize: 45.sp)),  
23 - ),  
24 - builder: (context, widget) {  
25 - ScreenUtil.setContext(context);  
26 - return MediaQuery(  
27 - //Setting font does not change with system font size  
28 - data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),  
29 - child: widget,  
30 - );  
31 - },  
32 - home: HomePage(title: 'FlutterScreenUtil Demo'),  
33 - ),  
34 - );  
35 - }  
36 -}  
37 -  
38 -class HomePage extends StatefulWidget {  
39 - const HomePage({Key key, this.title}) : super(key: key);  
40 -  
41 - final String title;  
42 -  
43 - @override  
44 - _HomePageState createState() => _HomePageState();  
45 -}  
46 -  
47 -class _HomePageState extends State<HomePage> {  
48 - @override  
49 - Widget build(BuildContext context) {  
50 - printScreenInformation();  
51 - return Scaffold(  
52 - appBar: AppBar(  
53 - title: Text(widget.title),  
54 - ),  
55 - body: SingleChildScrollView(  
56 - child: Column(  
57 - crossAxisAlignment: CrossAxisAlignment.start,  
58 - children: <Widget>[  
59 - Row(  
60 - children: <Widget>[  
61 - // Using Extensions  
62 - Container(  
63 - padding: EdgeInsets.all(10.w),  
64 - width: 0.5.sw,  
65 - height: 200.h,  
66 - color: Colors.red,  
67 - child: Text(  
68 - 'My actual width: ${0.5.sw}dp \n\n'  
69 - 'My actual height: ${200.h}dp',  
70 - style: TextStyle(  
71 - color: Colors.white,  
72 - fontSize: 12.sp,  
73 - ),  
74 - ),  
75 - ),  
76 - // Without using Extensions  
77 - Container(  
78 - padding: EdgeInsets.all(ScreenUtil().setWidth(10)),  
79 - width: ScreenUtil().setWidth(180),  
80 - height: ScreenUtil().setHeight(200),  
81 - color: Colors.blue,  
82 - child: Text(  
83 - 'My design draft width: 180dp\n\n'  
84 - 'My design draft height: 200dp',  
85 - style: TextStyle(  
86 - color: Colors.white,  
87 - fontSize: ScreenUtil().setSp(12),  
88 - ),  
89 - ),  
90 - ),  
91 - ],  
92 - ),  
93 - Container(  
94 - padding: EdgeInsets.all(10.w),  
95 - width: 100.r,  
96 - height: 100.r,  
97 - color: Colors.green,  
98 - child: Text(  
99 - 'I am a square with a side length of 100',  
100 - style: TextStyle(  
101 - color: Colors.white,  
102 - fontSize: 12.sp,  
103 - ),  
104 - ),  
105 - ),  
106 - Text('Device width:${ScreenUtil().screenWidth}dp'),  
107 - Text('Device height:${ScreenUtil().screenHeight}dp'),  
108 - Text('Device pixel density:${ScreenUtil().pixelRatio}'),  
109 - Text('Bottom safe zone distance:${ScreenUtil().bottomBarHeight}dp'),  
110 - Text('Status bar height:${ScreenUtil().statusBarHeight}dp'),  
111 - Text(  
112 - 'The ratio of actual width to UI design:${ScreenUtil().scaleWidth}',  
113 - textAlign: TextAlign.center,  
114 - ),  
115 - Text(  
116 - 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}',  
117 - textAlign: TextAlign.center,  
118 - ),  
119 - SizedBox(  
120 - height: 10.h,  
121 - ),  
122 - Text('System font scaling factor:${ScreenUtil().textScaleFactor}'),  
123 - SizedBox(height: 5),  
124 - Column(  
125 - crossAxisAlignment: CrossAxisAlignment.start,  
126 - children: <Widget>[  
127 - Text(  
128 - '16sp, will not change with the system.',  
129 - style: TextStyle(  
130 - color: Colors.black,  
131 - fontSize: 16.sp,  
132 - ),  
133 - textScaleFactor: 1.0,  
134 - ),  
135 - Text(  
136 - '16sp,if data is not set in MediaQuery,my font size will change with the system.',  
137 - style: TextStyle(  
138 - color: Colors.black,  
139 - fontSize: 16.sp,  
140 - ),  
141 - ),  
142 - ],  
143 - )  
144 - ],  
145 - ),  
146 - ),  
147 - floatingActionButton: FloatingActionButton(  
148 - onPressed: () {  
149 - SystemChrome.setPreferredOrientations([  
150 - MediaQuery.of(context).orientation == Orientation.portrait  
151 - ? DeviceOrientation.landscapeRight  
152 - : DeviceOrientation.portraitUp,  
153 - ]);  
154 - // setState(() {});  
155 - },  
156 - child: Icon(Icons.screen_rotation),  
157 - ),  
158 - );  
159 - }  
160 -  
161 - void printScreenInformation() {  
162 - print('Device Size:${Size(1.sw, 1.sh)}');  
163 - print('Device pixel density:${ScreenUtil().pixelRatio}');  
164 - print('Bottom safe zone distance dp:${ScreenUtil().bottomBarHeight}dp');  
165 - print('Status bar height dp:${ScreenUtil().statusBarHeight}dp');  
166 - print('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}');  
167 - print(  
168 - 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}');  
169 - print('System font scaling:${ScreenUtil().textScaleFactor}');  
170 - print('0.5 times the screen width:${0.5.sw}dp');  
171 - print('0.5 times the screen height:${0.5.sh}dp');  
172 - print('Screen orientation:${ScreenUtil().orientation}');  
173 - } 6 + const method = int.fromEnvironment('method', defaultValue: 1);
  7 + runApp(method == 1 ? firstMethod.MyApp() : secondMethod.MyApp());
174 } 8 }
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_screenutil/flutter_screenutil.dart'; 1 +import 'package:flutter/widgets.dart';
  2 +import 'src_zh/first_method.dart' as firstMethod;
  3 +import 'src_zh/second_method.dart' as secondMethod;
3 4
4 -void main() => runApp(MyApp()); 5 +void main() {
  6 + const method = int.fromEnvironment('method', defaultValue: 1);
5 7
6 -class MyApp extends StatelessWidget {  
7 - @override  
8 - Widget build(BuildContext context) {  
9 - return MaterialApp(  
10 - debugShowCheckedModeBanner: false,  
11 - title: 'Flutter_ScreenUtil',  
12 - theme: ThemeData(  
13 - primarySwatch: Colors.blue,  
14 - ),  
15 - home: HomePage(title: 'FlutterScreenUtil Demo'),  
16 - );  
17 - }  
18 -}  
19 -  
20 -class HomePage extends StatefulWidget {  
21 - const HomePage({Key key, this.title}) : super(key: key);  
22 -  
23 - final String title;  
24 -  
25 - @override  
26 - _HomePageState createState() => _HomePageState();  
27 -}  
28 -  
29 -class _HomePageState extends State<HomePage> {  
30 - @override  
31 - Widget build(BuildContext context) {  
32 - //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  
33 - ScreenUtil.init(  
34 - BoxConstraints(  
35 - maxWidth: MediaQuery.of(context).size.width,  
36 - maxHeight: MediaQuery.of(context).size.height),  
37 - designSize: Size(360, 690),  
38 - context: context,  
39 - );  
40 - printScreenInformation();  
41 - return Scaffold(  
42 - appBar: AppBar(  
43 - title: Text(widget.title),  
44 - ),  
45 - body: SingleChildScrollView(  
46 - child: Column(  
47 - crossAxisAlignment: CrossAxisAlignment.center,  
48 - children: <Widget>[  
49 - Row(  
50 - children: <Widget>[  
51 - Container(  
52 - padding: EdgeInsets.all(ScreenUtil().setWidth(10)),  
53 - width: 180.w,  
54 - height: 200.h,  
55 - color: Colors.red,  
56 - child: Text(  
57 - '我的实际宽度:${180.w}dp \n'  
58 - '我的实际高度:${200.h}dp',  
59 - style: TextStyle(color: Colors.white, fontSize: 12.sp),  
60 - ),  
61 - ),  
62 - Container(  
63 - padding: EdgeInsets.all(ScreenUtil().setWidth(10)),  
64 - width: ScreenUtil().setWidth(180),  
65 - height: ScreenUtil().setHeight(200),  
66 - color: Colors.blue,  
67 - child: Text(  
68 - '我的设计稿宽度: 180dp \n'  
69 - '我的设计稿高度: 200dp',  
70 - style: TextStyle(  
71 - color: Colors.white,  
72 - fontSize: ScreenUtil().setSp(12))),  
73 - ),  
74 - ],  
75 - ),  
76 - Container(  
77 - padding: EdgeInsets.all(ScreenUtil().setWidth(10)),  
78 - width: 100.r,  
79 - height: 100.r,  
80 - color: Colors.green,  
81 - child: Text(  
82 - '我是正方形,边长是100',  
83 - style: TextStyle(  
84 - color: Colors.white,  
85 - fontSize: ScreenUtil().setSp(12),  
86 - ),  
87 - ),  
88 - ),  
89 - Text('设备宽度:${ScreenUtil().screenWidth}dp'),  
90 - Text('设备高度:${ScreenUtil().screenHeight}dp'),  
91 - Text('设备的像素密度:${ScreenUtil().pixelRatio}'),  
92 - Text('底部安全区距离:${ScreenUtil().bottomBarHeight}dp'),  
93 - Text('状态栏高度:${ScreenUtil().statusBarHeight}dp'),  
94 - Text(  
95 - '实际宽度与设计稿的比例:${ScreenUtil().scaleWidth}',  
96 - textAlign: TextAlign.center,  
97 - ),  
98 - Text(  
99 - '实际高度与设计稿的比例:${ScreenUtil().scaleHeight}',  
100 - textAlign: TextAlign.center,  
101 - ),  
102 - SizedBox(  
103 - height: 50.h,  
104 - ),  
105 - Text('系统的字体缩放比例:${ScreenUtil().textScaleFactor}'),  
106 - Column(  
107 - crossAxisAlignment: CrossAxisAlignment.start,  
108 - children: <Widget>[  
109 - Text(  
110 - '我的文字大小在设计稿上是16dp,因为设置了`textScaleFactor`,所以不会随着系统的文字缩放比例变化',  
111 - style: TextStyle(  
112 - color: Colors.black,  
113 - fontSize: 16.sp,  
114 - ),  
115 - textScaleFactor: 1.0,  
116 - ),  
117 - Text(  
118 - '我的文字大小在设计稿上是16dp,会随着系统的文字缩放比例变化',  
119 - style: TextStyle(  
120 - color: Colors.black,  
121 - fontSize: 16.sp,  
122 - ),  
123 - ),  
124 - ],  
125 - )  
126 - ],  
127 - ),  
128 - ),  
129 - );  
130 - }  
131 -  
132 - void printScreenInformation() {  
133 - print('设备宽度:${1.sw}dp');  
134 - print('设备高度:${1.sh}dp');  
135 - print('设备的像素密度:${ScreenUtil().pixelRatio}');  
136 - print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');  
137 - print('状态栏高度:${ScreenUtil().statusBarHeight}dp');  
138 - print('实际宽度和字体(dp)与设计稿(dp)的比例:${ScreenUtil().scaleWidth}');  
139 - print('实际高度(dp)与设计稿(dp)的比例:${ScreenUtil().scaleHeight}');  
140 - print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight}');  
141 - print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');  
142 - print('屏幕宽度的0.5:${0.5.sw}dp');  
143 - print('屏幕高度的0.5:${0.5.sh}dp');  
144 - print('屏幕方向:${ScreenUtil().orientation}');  
145 - } 8 + runApp(method == 1 ? firstMethod.MyApp() : secondMethod.MyApp());
146 } 9 }
  1 +import 'package:example/src/home.dart';
  2 +import 'package:flutter/material.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +class MyApp extends StatelessWidget {
  6 + const MyApp({Key? key}) : super(key: key);
  7 +
  8 + @override
  9 + Widget build(BuildContext context) {
  10 + // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
  11 + return ScreenUtilInit(
  12 + builder: (context) {
  13 + return MaterialApp(
  14 + debugShowCheckedModeBanner: false,
  15 + // Use this line to prevent extra rebuilds
  16 + useInheritedMediaQuery: true,
  17 + title: 'First Method',
  18 + // You can use the library anywhere in the app even in theme
  19 + theme: ThemeData(
  20 + primarySwatch: Colors.blue,
  21 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
  22 + ),
  23 + home: HomePage(title: 'First Method'),
  24 + );
  25 + },
  26 + );
  27 + }
  28 +}
  29 +
  30 +class HomePage extends StatefulWidget {
  31 + const HomePage({Key? key, required this.title}) : super(key: key);
  32 +
  33 + final String title;
  34 +
  35 + @override
  36 + _HomePageState createState() => _HomePageState();
  37 +}
  38 +
  39 +class _HomePageState extends State<HomePage> {
  40 + @override
  41 + Widget build(BuildContext context) => HomePageScaffold(title: widget.title);
  42 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter/services.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +class HomePageScaffold extends StatelessWidget {
  6 + const HomePageScaffold({Key? key, required this.title}) : super(key: key);
  7 +
  8 + void printScreenInformation() {
  9 + print('Device Size:${Size(1.sw, 1.sh)}');
  10 + print('Device pixel density:${ScreenUtil().pixelRatio}');
  11 + print('Bottom safe zone distance dp:${ScreenUtil().bottomBarHeight}dp');
  12 + print('Status bar height dp:${ScreenUtil().statusBarHeight}dp');
  13 + print('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}');
  14 + print(
  15 + 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}');
  16 + print('System font scaling:${ScreenUtil().textScaleFactor}');
  17 + print('0.5 times the screen width:${0.5.sw}dp');
  18 + print('0.5 times the screen height:${0.5.sh}dp');
  19 + print('Screen orientation:${ScreenUtil().orientation}');
  20 + }
  21 +
  22 + @override
  23 + Widget build(BuildContext context) {
  24 + printScreenInformation();
  25 +
  26 + return Scaffold(
  27 + appBar: AppBar(
  28 + title: Text(title),
  29 + ),
  30 + body: SingleChildScrollView(
  31 + child: Column(
  32 + crossAxisAlignment: CrossAxisAlignment.start,
  33 + children: <Widget>[
  34 + Row(
  35 + children: <Widget>[
  36 + // Using Extensions
  37 + Container(
  38 + padding: EdgeInsets.all(10.w),
  39 + width: 0.5.sw,
  40 + height: 200.h,
  41 + color: Colors.red,
  42 + child: Text(
  43 + 'My actual width: ${0.5.sw}dp \n\n'
  44 + 'My actual height: ${200.h}dp',
  45 + style: TextStyle(
  46 + color: Colors.white,
  47 + fontSize: 12.sp,
  48 + ),
  49 + ),
  50 + ),
  51 + // Without using Extensions
  52 + Container(
  53 + padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
  54 + width: ScreenUtil().setWidth(180),
  55 + height: ScreenUtil().setHeight(200),
  56 + color: Colors.blue,
  57 + child: Text(
  58 + 'My design draft width: 180dp\n\n'
  59 + 'My design draft height: 200dp',
  60 + style: TextStyle(
  61 + color: Colors.white,
  62 + fontSize: ScreenUtil().setSp(12),
  63 + ),
  64 + ),
  65 + ),
  66 + ],
  67 + ),
  68 + Container(
  69 + padding: EdgeInsets.all(10.w),
  70 + width: 100.r,
  71 + height: 100.r,
  72 + color: Colors.green,
  73 + child: Text(
  74 + 'I am a square with a side length of 100',
  75 + style: TextStyle(
  76 + color: Colors.white,
  77 + fontSize: 12.sp,
  78 + ),
  79 + ),
  80 + ),
  81 + Text('Device width:${ScreenUtil().screenWidth}dp'),
  82 + Text('Device height:${ScreenUtil().screenHeight}dp'),
  83 + Text('Device pixel density:${ScreenUtil().pixelRatio}'),
  84 + Text('Bottom safe zone distance:${ScreenUtil().bottomBarHeight}dp'),
  85 + Text('Status bar height:${ScreenUtil().statusBarHeight}dp'),
  86 + Text(
  87 + 'The ratio of actual width to UI design:${ScreenUtil().scaleWidth}',
  88 + textAlign: TextAlign.center,
  89 + ),
  90 + Text(
  91 + 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}',
  92 + textAlign: TextAlign.center,
  93 + ),
  94 + SizedBox(
  95 + height: 10.h,
  96 + ),
  97 + Text('System font scaling factor:${ScreenUtil().textScaleFactor}'),
  98 + SizedBox(height: 5),
  99 + Column(
  100 + crossAxisAlignment: CrossAxisAlignment.start,
  101 + children: <Widget>[
  102 + Text(
  103 + '16sp, will not change with the system.',
  104 + style: TextStyle(
  105 + color: Colors.black,
  106 + fontSize: 16.sp,
  107 + ),
  108 + textScaleFactor: 1.0,
  109 + ),
  110 + Text(
  111 + '16sp,if data is not set in MediaQuery,my font size will change with the system.',
  112 + style: TextStyle(
  113 + color: Colors.black,
  114 + fontSize: 16.sp,
  115 + ),
  116 + ),
  117 + ],
  118 + )
  119 + ],
  120 + ),
  121 + ),
  122 + floatingActionButton: FloatingActionButton.extended(
  123 + onPressed: () {
  124 + SystemChrome.setPreferredOrientations([
  125 + MediaQuery.of(context).orientation == Orientation.portrait
  126 + ? DeviceOrientation.landscapeRight
  127 + : DeviceOrientation.portraitUp,
  128 + ]);
  129 + // setState(() {});
  130 + },
  131 + label: const Text('Rotate'),
  132 + ),
  133 + );
  134 + }
  135 +
  136 + final String title;
  137 +}
  1 +import 'package:example/src/home.dart';
  2 +import 'package:flutter/material.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +/// Note that you still can use [Theme] to theme your widget, but if you want
  6 +/// to theme MaterialApp you must use ScreenUtil.init in builder method and
  7 +/// wrap child with Theme, and remove theme and home properties from MaterialApp.
  8 +/// See [MyThemedApp].
  9 +///
  10 +/// example
  11 +/// ```dart
  12 +/// Theme(
  13 +/// data: ThemeData(...),
  14 +/// child: widget,
  15 +/// )
  16 +/// ```
  17 +class MyApp extends StatelessWidget {
  18 + const MyApp({Key? key}) : super(key: key);
  19 +
  20 + @override
  21 + Widget build(BuildContext context) {
  22 + // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
  23 + return MaterialApp(
  24 + debugShowCheckedModeBanner: false,
  25 + title: 'Second Method',
  26 + theme: ThemeData(
  27 + primarySwatch: Colors.blue,
  28 + ),
  29 + home: HomePage(title: 'Second Method'),
  30 + );
  31 + }
  32 +}
  33 +
  34 +class HomePage extends StatefulWidget {
  35 + const HomePage({Key? key, required this.title}) : super(key: key);
  36 +
  37 + final String title;
  38 +
  39 + @override
  40 + _HomePageState createState() => _HomePageState();
  41 +}
  42 +
  43 +class _HomePageState extends State<HomePage> {
  44 + @override
  45 + Widget build(BuildContext context) {
  46 + ScreenUtil.init(context);
  47 + return HomePageScaffold(title: widget.title);
  48 + }
  49 +}
  50 +
  51 +class MyThemedApp extends StatelessWidget {
  52 + const MyThemedApp({Key? key}) : super(key: key);
  53 +
  54 + @override
  55 + Widget build(BuildContext context) {
  56 + return MaterialApp(
  57 + debugShowCheckedModeBanner: false,
  58 + title: 'First Method (Themed)',
  59 + builder: (ctx, child) {
  60 + return Theme(
  61 + data: ThemeData(
  62 + primarySwatch: Colors.blue,
  63 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
  64 + ),
  65 + child: HomePage(title: 'FlutterScreenUtil Demo'),
  66 + );
  67 + },
  68 + );
  69 + }
  70 +}
  1 +import 'package:example/src_zh/home.dart';
  2 +import 'package:flutter/material.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +class MyApp extends StatelessWidget {
  6 + const MyApp({Key? key}) : super(key: key);
  7 +
  8 + @override
  9 + Widget build(BuildContext context) {
  10 + // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
  11 + return ScreenUtilInit(
  12 + builder: (context) {
  13 + return MaterialApp(
  14 + debugShowCheckedModeBanner: false,
  15 + title: '第一种方法',
  16 + // You can use the library anywhere in the app even in theme
  17 + theme: ThemeData(
  18 + primarySwatch: Colors.blue,
  19 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
  20 + ),
  21 + home: HomePage(title: '第一种方法'),
  22 + );
  23 + },
  24 + );
  25 + }
  26 +}
  27 +
  28 +class HomePage extends StatefulWidget {
  29 + const HomePage({Key? key, required this.title}) : super(key: key);
  30 +
  31 + final String title;
  32 +
  33 + @override
  34 + _HomePageState createState() => _HomePageState();
  35 +}
  36 +
  37 +class _HomePageState extends State<HomePage> {
  38 + @override
  39 + Widget build(BuildContext context) => HomePageScaffold(title: widget.title);
  40 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter/services.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +class HomePageScaffold extends StatelessWidget {
  6 + const HomePageScaffold({Key? key, required this.title}) : super(key: key);
  7 +
  8 + void printScreenInformation() {
  9 + print('设备宽度:${1.sw}dp');
  10 + print('设备高度:${1.sh}dp');
  11 + print('设备的像素密度:${ScreenUtil().pixelRatio}');
  12 + print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');
  13 + print('状态栏高度:${ScreenUtil().statusBarHeight}dp');
  14 + print('实际宽度和字体(dp)与设计稿(dp)的比例:${ScreenUtil().scaleWidth}');
  15 + print('实际高度(dp)与设计稿(dp)的比例:${ScreenUtil().scaleHeight}');
  16 + print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight}');
  17 + print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');
  18 + print('屏幕宽度的0.5:${0.5.sw}dp');
  19 + print('屏幕高度的0.5:${0.5.sh}dp');
  20 + print('屏幕方向:${ScreenUtil().orientation}');
  21 + }
  22 +
  23 + @override
  24 + Widget build(BuildContext context) {
  25 + printScreenInformation();
  26 +
  27 + return Scaffold(
  28 + appBar: AppBar(
  29 + title: Text(title),
  30 + ),
  31 + body: SingleChildScrollView(
  32 + child: Column(
  33 + crossAxisAlignment: CrossAxisAlignment.center,
  34 + children: <Widget>[
  35 + Row(
  36 + children: <Widget>[
  37 + Container(
  38 + padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
  39 + width: 180.w,
  40 + height: 200.h,
  41 + color: Colors.red,
  42 + child: Text(
  43 + '我的实际宽度:${180.w}dp \n'
  44 + '我的实际高度:${200.h}dp',
  45 + style: TextStyle(color: Colors.white, fontSize: 12.sp),
  46 + ),
  47 + ),
  48 + Container(
  49 + padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
  50 + width: ScreenUtil().setWidth(180),
  51 + height: ScreenUtil().setHeight(200),
  52 + color: Colors.blue,
  53 + child: Text(
  54 + '我的设计稿宽度: 180dp \n'
  55 + '我的设计稿高度: 200dp',
  56 + style: TextStyle(
  57 + color: Colors.white,
  58 + fontSize: ScreenUtil().setSp(12))),
  59 + ),
  60 + ],
  61 + ),
  62 + Container(
  63 + padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
  64 + width: 100.r,
  65 + height: 100.r,
  66 + color: Colors.green,
  67 + child: Text(
  68 + '我是正方形,边长是100',
  69 + style: TextStyle(
  70 + color: Colors.white,
  71 + fontSize: ScreenUtil().setSp(12),
  72 + ),
  73 + ),
  74 + ),
  75 + Text('设备宽度:${ScreenUtil().screenWidth}dp'),
  76 + Text('设备高度:${ScreenUtil().screenHeight}dp'),
  77 + Text('设备的像素密度:${ScreenUtil().pixelRatio}'),
  78 + Text('底部安全区距离:${ScreenUtil().bottomBarHeight}dp'),
  79 + Text('状态栏高度:${ScreenUtil().statusBarHeight}dp'),
  80 + Text(
  81 + '实际宽度与设计稿的比例:${ScreenUtil().scaleWidth}',
  82 + textAlign: TextAlign.center,
  83 + ),
  84 + Text(
  85 + '实际高度与设计稿的比例:${ScreenUtil().scaleHeight}',
  86 + textAlign: TextAlign.center,
  87 + ),
  88 + SizedBox(
  89 + height: 50.h,
  90 + ),
  91 + Text('系统的字体缩放比例:${ScreenUtil().textScaleFactor}'),
  92 + Column(
  93 + crossAxisAlignment: CrossAxisAlignment.start,
  94 + children: <Widget>[
  95 + Text(
  96 + '我的文字大小在设计稿上是16dp,因为设置了`textScaleFactor`,所以不会随着系统的文字缩放比例变化',
  97 + style: TextStyle(
  98 + color: Colors.black,
  99 + fontSize: 16.sp,
  100 + ),
  101 + textScaleFactor: 1.0,
  102 + ),
  103 + Text(
  104 + '我的文字大小在设计稿上是16dp,会随着系统的文字缩放比例变化',
  105 + style: TextStyle(
  106 + color: Colors.black,
  107 + fontSize: 16.sp,
  108 + ),
  109 + ),
  110 + ],
  111 + )
  112 + ],
  113 + ),
  114 + ),
  115 + floatingActionButton: FloatingActionButton.extended(
  116 + onPressed: () {
  117 + SystemChrome.setPreferredOrientations([
  118 + MediaQuery.of(context).orientation == Orientation.portrait
  119 + ? DeviceOrientation.landscapeRight
  120 + : DeviceOrientation.portraitUp,
  121 + ]);
  122 + // setState(() {});
  123 + },
  124 + label: const Text('旋转'),
  125 + ),
  126 + );
  127 + }
  128 +
  129 + final String title;
  130 +}
  1 +import 'package:example/src_zh/home.dart';
  2 +import 'package:flutter/material.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +
  5 +/// 请注意,您仍然可以使用 [Theme] 为您的小部件设置主题,但如果您想为 MaterialApp
  6 +/// 设置主题,您必须在 builder 方法中使用 ScreenUtil.init 并使用 Theme 包装子项
  7 +/// 并从 MaterialApp 中删除主题和主页属性。 请参阅 [MyThemedApp]。
  8 +///
  9 +/// 例子
  10 +/// ```dart
  11 +/// Theme(
  12 +/// data: ThemeData(...),
  13 +/// child: widget,
  14 +/// )
  15 +/// ```
  16 +class MyApp extends StatelessWidget {
  17 + const MyApp({Key? key}) : super(key: key);
  18 +
  19 + @override
  20 + Widget build(BuildContext context) {
  21 + // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
  22 + return MaterialApp(
  23 + debugShowCheckedModeBanner: false,
  24 + title: '第二种方法',
  25 + theme: ThemeData(
  26 + primarySwatch: Colors.blue,
  27 + ),
  28 + home: HomePage(title: '第二种方法'),
  29 + );
  30 + }
  31 +}
  32 +
  33 +class HomePage extends StatefulWidget {
  34 + const HomePage({Key? key, required this.title}) : super(key: key);
  35 +
  36 + final String title;
  37 +
  38 + @override
  39 + _HomePageState createState() => _HomePageState();
  40 +}
  41 +
  42 +class _HomePageState extends State<HomePage> {
  43 + @override
  44 + Widget build(BuildContext context) {
  45 + ScreenUtil.init(context);
  46 + return HomePageScaffold(title: widget.title);
  47 + }
  48 +}
  49 +
  50 +class MyThemedApp extends StatelessWidget {
  51 + const MyThemedApp({Key? key}) : super(key: key);
  52 +
  53 + @override
  54 + Widget build(BuildContext context) {
  55 + return MaterialApp(
  56 + debugShowCheckedModeBanner: false,
  57 + title: '第二种方法(带主题)',
  58 + builder: (ctx, child) {
  59 + return Theme(
  60 + data: ThemeData(
  61 + primarySwatch: Colors.blue,
  62 + textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)),
  63 + ),
  64 + child: HomePage(title: '第二种方法(带主题)'),
  65 + );
  66 + },
  67 + );
  68 + }
  69 +}
1 name: example 1 name: example
2 description: flutter_screenutil的使用示例 2 description: flutter_screenutil的使用示例
  3 +publish_to: none
3 4
4 # The following defines the version and build number for your application. 5 # The following defines the version and build number for your application.
5 # A version number is three numbers separated by dots, like 1.2.43 6 # A version number is three numbers separated by dots, like 1.2.43
@@ -10,20 +11,16 @@ description: flutter_screenutil的使用示例 @@ -10,20 +11,16 @@ description: flutter_screenutil的使用示例
10 version: 1.0.0+1 11 version: 1.0.0+1
11 12
12 environment: 13 environment:
13 - sdk: ">=2.0.0-dev.68.0 <3.0.0" 14 + sdk: ">=2.12.0 <3.0.0"
14 15
15 dependencies: 16 dependencies:
16 flutter: 17 flutter:
17 sdk: flutter 18 sdk: flutter
18 19
19 flutter_screenutil: 20 flutter_screenutil:
  21 + path: ../
20 22
21 dev_dependencies: 23 dev_dependencies:
22 flutter_test: 24 flutter_test:
23 sdk: flutter 25 sdk: flutter
24 test: ^1.15.7 26 test: ^1.15.7
25 -  
26 -dependency_overrides:  
27 - flutter_screenutil:  
28 - path: ../  
29 -  
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 import 'package:flutter/material.dart'; 8 import 'package:flutter/material.dart';
9 import 'package:flutter_test/flutter_test.dart'; 9 import 'package:flutter_test/flutter_test.dart';
10 10
11 -import 'package:example/main.dart'; 11 +import 'package:example/src/first_method.dart';
12 12
13 void main() { 13 void main() {
14 testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 testWidgets('Counter increments smoke test', (WidgetTester tester) async {
@@ -3,9 +3,10 @@ @@ -3,9 +3,10 @@
3 * email: zhuoyuan93@gmail.com 3 * email: zhuoyuan93@gmail.com
4 */ 4 */
5 5
6 -import 'dart:math'; 6 +import 'dart:math' show min, max;
  7 +import 'dart:ui' show FlutterWindow;
7 8
8 -import 'package:flutter/material.dart'; 9 +import 'package:flutter/widgets.dart';
9 10
10 class ScreenUtil { 11 class ScreenUtil {
11 static const Size defaultSize = Size(360, 690); 12 static const Size defaultSize = Size(360, 690);
@@ -21,7 +22,7 @@ class ScreenUtil { @@ -21,7 +22,7 @@ class ScreenUtil {
21 late double _screenWidth; 22 late double _screenWidth;
22 late double _screenHeight; 23 late double _screenHeight;
23 late bool _minTextAdapt; 24 late bool _minTextAdapt;
24 - late BuildContext? context; 25 + BuildContext? context;
25 late bool _splitScreenMode; 26 late bool _splitScreenMode;
26 27
27 ScreenUtil._(); 28 ScreenUtil._();
@@ -30,26 +31,74 @@ class ScreenUtil { @@ -30,26 +31,74 @@ class ScreenUtil {
30 return _instance; 31 return _instance;
31 } 32 }
32 33
  34 + /// Manually wait for window size to be initialized
  35 + ///
  36 + /// `Recommended` to use before you need access window size
  37 + /// or in custom splash/bootstrap screen [FutureBuilder]
  38 + ///
  39 + /// example:
  40 + /// ```dart
  41 + /// ...
  42 + /// ScreenUtil.init(context, ...);
  43 + /// ...
  44 + /// FutureBuilder(
  45 + /// future: Future.wait([..., ensureScreenSize(), ...]),
  46 + /// builder: (context, snapshot) {
  47 + /// if (snapshot.hasData) return const HomeScreen();
  48 + /// return Material(
  49 + /// child: LayoutBuilder(
  50 + /// ...
  51 + /// ),
  52 + /// );
  53 + /// },
  54 + /// )
  55 + /// ```
  56 + static Future<void> ensureScreenSize([
  57 + FlutterWindow? window,
  58 + Duration duration = const Duration(milliseconds: 10),
  59 + ]) async {
  60 + final binding = WidgetsFlutterBinding.ensureInitialized();
  61 + window ??= binding.window;
  62 +
  63 + if (window.viewConfiguration.geometry.isEmpty) {
  64 + return Future.delayed(duration, () async {
  65 + binding.deferFirstFrame();
  66 + await ensureScreenSize(window, duration);
  67 + return binding.allowFirstFrame();
  68 + });
  69 + }
  70 + }
  71 +
33 static void setContext(BuildContext context) { 72 static void setContext(BuildContext context) {
34 _instance.context = context; 73 _instance.context = context;
35 } 74 }
36 75
  76 + /// Initializing the library.
37 static void init( 77 static void init(
38 - BoxConstraints constraints, {  
39 - BuildContext? context,  
40 - Orientation orientation = Orientation.portrait, 78 + BuildContext context, {
  79 + Orientation? orientation,
  80 + Size? deviceSize,
41 Size designSize = defaultSize, 81 Size designSize = defaultSize,
42 bool splitScreenMode = false, 82 bool splitScreenMode = false,
43 bool minTextAdapt = false, 83 bool minTextAdapt = false,
44 }) { 84 }) {
  85 + print('init called');
  86 + final deviceData = MediaQuery.maybeOf(context).nonEmptySizeOrNull();
  87 +
  88 + deviceSize ??= deviceData?.size ?? designSize;
  89 + orientation ??= deviceData?.orientation ??
  90 + (deviceSize.width > deviceSize.height
  91 + ? Orientation.landscape
  92 + : Orientation.portrait);
  93 +
45 _instance = ScreenUtil._() 94 _instance = ScreenUtil._()
46 ..uiSize = designSize 95 ..uiSize = designSize
47 .._splitScreenMode = splitScreenMode 96 .._splitScreenMode = splitScreenMode
48 .._minTextAdapt = minTextAdapt 97 .._minTextAdapt = minTextAdapt
49 .._orientation = orientation 98 .._orientation = orientation
50 - .._screenWidth = constraints.maxWidth  
51 - .._screenHeight = constraints.maxHeight;  
52 - if (context != null) setContext(context); 99 + .._screenWidth = deviceSize.width
  100 + .._screenHeight = deviceSize.height
  101 + ..context = deviceData != null ? context : null;
53 } 102 }
54 103
55 ///获取屏幕方向 104 ///获取屏幕方向
@@ -138,3 +187,12 @@ class ScreenUtil { @@ -138,3 +187,12 @@ class ScreenUtil {
138 Widget setVerticalSpacingRadius(num height) => 187 Widget setVerticalSpacingRadius(num height) =>
139 SizedBox(height: radius(height)); 188 SizedBox(height: radius(height));
140 } 189 }
  190 +
  191 +extension on MediaQueryData? {
  192 + MediaQueryData? nonEmptySizeOrNull() {
  193 + if (this?.size.isEmpty ?? true)
  194 + return null;
  195 + else
  196 + return this;
  197 + }
  198 +}
1 -import 'package:flutter/cupertino.dart'; 1 +import 'package:flutter/widgets.dart';
  2 +import 'package:flutter/rendering.dart';
2 3
3 import 'screen_util.dart'; 4 import 'screen_util.dart';
4 5
@@ -12,7 +13,7 @@ class ScreenUtilInit extends StatelessWidget { @@ -12,7 +13,7 @@ class ScreenUtilInit extends StatelessWidget {
12 Key? key, 13 Key? key,
13 }) : super(key: key); 14 }) : super(key: key);
14 15
15 - final Widget Function() builder; 16 + final WidgetBuilder builder;
16 final bool splitScreenMode; 17 final bool splitScreenMode;
17 final bool minTextAdapt; 18 final bool minTextAdapt;
18 19
@@ -20,24 +21,26 @@ class ScreenUtilInit extends StatelessWidget { @@ -20,24 +21,26 @@ class ScreenUtilInit extends StatelessWidget {
20 final Size designSize; 21 final Size designSize;
21 22
22 @override 23 @override
23 - Widget build(BuildContext context) {  
24 - return MediaQuery(  
25 - data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window),  
26 - child: LayoutBuilder(builder: (_, BoxConstraints constraints) {  
27 - if (constraints.maxWidth != 0) {  
28 - final Orientation orientation =  
29 - constraints.maxWidth > constraints.maxHeight  
30 - ? Orientation.landscape  
31 - : Orientation.portrait;  
32 - ScreenUtil.init(constraints,  
33 - context: _,  
34 - orientation: orientation, 24 + Widget build(BuildContext _) {
  25 + bool firstFrameAllowed = false;
  26 + RendererBinding.instance!.deferFirstFrame();
  27 +
  28 + return MediaQuery.fromWindow(
  29 + child: Builder(builder: (context) {
  30 + if (MediaQuery.of(context).size == Size.zero) return const SizedBox();
  31 + ScreenUtil.init(
  32 + context,
35 designSize: designSize, 33 designSize: designSize,
36 splitScreenMode: splitScreenMode, 34 splitScreenMode: splitScreenMode,
37 - minTextAdapt: minTextAdapt);  
38 - return builder(); 35 + minTextAdapt: minTextAdapt,
  36 + );
  37 +
  38 + if (!firstFrameAllowed) {
  39 + RendererBinding.instance!.allowFirstFrame();
  40 + firstFrameAllowed = true;
39 } 41 }
40 - return Container(); 42 +
  43 + return builder(context);
41 }), 44 }),
42 ); 45 );
43 } 46 }
@@ -71,9 +71,7 @@ extension BorderRaduisExtension on BorderRadius { @@ -71,9 +71,7 @@ extension BorderRaduisExtension on BorderRadius {
71 71
72 extension RaduisExtension on Radius { 72 extension RaduisExtension on Radius {
73 /// Creates adapt Radius using r [SizeExtension]. 73 /// Creates adapt Radius using r [SizeExtension].
74 - Radius get r => this  
75 - ..x.r  
76 - ..y.r; 74 + Radius get r => Radius.elliptical(x.r, y.r);
77 } 75 }
78 76
79 extension BoxConstraintsExtension on BoxConstraints { 77 extension BoxConstraintsExtension on BoxConstraints {
1 name: flutter_screenutil 1 name: flutter_screenutil
2 description: A flutter plugin for adapting screen and font size.Guaranteed to look good on different models 2 description: A flutter plugin for adapting screen and font size.Guaranteed to look good on different models
3 -version: 5.3.0 3 +version: 5.3.2
4 homepage: https://github.com/OpenFlutter/flutter_screenutil 4 homepage: https://github.com/OpenFlutter/flutter_screenutil
5 publish_to: https://pub.dev 5 publish_to: https://pub.dev
6 6