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
Showing
21 changed files
with
744 additions
and
503 deletions
| 1 | # flutter_screenutil | 1 | # flutter_screenutil |
| 2 | + | ||
| 2 | [](https://pub.dev/packages/flutter_screenutil) | 3 | [](https://pub.dev/packages/flutter_screenutil) |
| 3 | [](https://pub.dev/packages/flutter_screenutil/score) | 4 | [](https://pub.dev/packages/flutter_screenutil/score) |
| 4 | [](https://pub.dev/packages/flutter_screenutil/score) | 5 | [](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 |  | 342 |  |
| 334 |  | 343 |  |
| @@ -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 | } |
example/android/gradle.properties
0 → 100644
| 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 | } |
example/lib/src/first_method.dart
0 → 100644
| 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 | +} |
example/lib/src/home.dart
0 → 100644
| 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 | +} |
example/lib/src/second_method.dart
0 → 100644
| 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 | +} |
example/lib/src_zh/first_method.dart
0 → 100644
| 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 | +} |
example/lib/src_zh/home.dart
0 → 100644
| 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 | +} |
example/lib/src_zh/second_method.dart
0 → 100644
| 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 |
-
Please register or login to post a comment