Committed by
GitHub
Major updates & fixes (#491)
* Clean codes & add features & fix bugs Features/Bugs: - Feature: You can select what classes needs to be rebuilt instead of rebuilding everything, if you have widget A, either addi SU mixin or add 'A' to list ScreenUtilInit.responsiveWidgets - Feature: Using ScreenUtilInit.builder is optional (use it only when using library in theme) - Bug: Second call to ScreenUtil.init ignores any existing values and uses the default values when not provided, use ScreenUtil.configure instead - Bug: ScreenUtil.ensureScreenSize raises an overflow error * Update version * Add List of flutter widgets * Update logic if allowing widget to being rebuilt * Little code solidity * Add scale factors: diagonal & diameter * Add option for how font size should be scaled * Update support to Dart >= 2.17.0 * Add fontSizeResolver to init + helpers * Add ensureScreenSize to ScreenUtilInit constructor * Fix ensureScreenSize on web * Update Runner.rc * Add some methods to extensions * Update widget_test * Remove extra deps * Clean code * Add ensureScreenSizeAndInit + make init sync * Update README.md * Update CHANGELOG.md * Update version to 5.9.0 * Rename version * Adding tests * Changing version in CHANGELOG.md --------- Co-authored-by: Mounir Bouaiche <mounir-b@dba.ma>
Showing
19 changed files
with
1363 additions
and
227 deletions
| 1 | +# 5.9.0-beta | ||
| 2 | +- ScreenUtilInit won't rebuild the whole widget tree | ||
| 3 | +- Add `fontSizeResolver` to specify how font size should be scaled | ||
| 4 | +- Add `diameter` & `diagonal` factors | ||
| 5 | +- `useInheritedMediaQuery` has not effect, and will be removed in next release | ||
| 6 | +- Fix `ensureScreenSize` in web platform | ||
| 7 | + | ||
| 1 | # 5.8.4 | 8 | # 5.8.4 |
| 2 | - bug fix | 9 | - bug fix |
| 3 | - change useInheritedMediaQuery default value to false | 10 | - change useInheritedMediaQuery default value to false |
| @@ -38,28 +38,36 @@ dependencies: | @@ -38,28 +38,36 @@ dependencies: | ||
| 38 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 38 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 39 | ``` | 39 | ``` |
| 40 | 40 | ||
| 41 | -### Property | ||
| 42 | - | ||
| 43 | -| Property | Type | Default Value | Description | | ||
| 44 | -| --------------- |--------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------| | ||
| 45 | -| deviceSize | Size | null | The size of the physical device | | ||
| 46 | -| designSize | Size | Size(360,690) | The size of the device screen in the design draft, in dp | | ||
| 47 | -| builder | Function | null | Return widget that uses the library in a property (ex: MaterialApp's theme) | | ||
| 48 | -| child | Widget | null | A part of builder that its dependencies/properties don't use the library | | ||
| 49 | -| rebuildFactor | Function | *default* | Returns whether to rebuild or not when screen metrics changes. | | ||
| 50 | -| orientation | Orientation | portrait | screen orientation | | ||
| 51 | -| splitScreenMode | bool | false | support for split screen | | ||
| 52 | -| minTextAdapt | bool | false | Whether to adapt the text according to the minimum of width and height | | ||
| 53 | -| context | BuildContext | null | Get physical device data if not provided, by MediaQuery.of(context) | | ||
| 54 | -| useInheritedMediaQuery | bool | false | Recommended use `false` avoid rebuild very frequently <br/><br/> ~~Set this to true for Flutter 3.10 to avoid keyboard overlay on TextField~~ | | 41 | +### Properties |
| 42 | + | ||
| 43 | +| Property | Type | Default Value | Description | | ||
| 44 | +| ---------------- |--------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------| | ||
| 45 | +| designSize | Size | Size(360,690) | The size of the device screen in the design draft, in dp | | ||
| 46 | +| builder | Function | null | Return widget that uses the library in a property (ex: MaterialApp's theme) | | ||
| 47 | +| child | Widget | null | A part of builder that its dependencies/properties don't use the library | | ||
| 48 | +| rebuildFactor | Function | *default* | Function that take old and new screen metrics and returns whether to rebuild or not when changes. | | ||
| 49 | +| splitScreenMode | bool | false | support for split screen | | ||
| 50 | +| minTextAdapt | bool | false | Whether to adapt the text according to the minimum of width and height | | ||
| 51 | +| context | BuildContext | null | Get physical device data if not provided, by MediaQuery.of(context) | | ||
| 52 | +| fontSizeResolver | Function | *default* | Function that specify how font size should be adapted. Default is that font size scale with width of screen. | | ||
| 53 | +| reponsiveWidgets | Iterable<String> | null | List/Set of widget names that should be included in rebuilding tree. (See [How flutter_screenutil marks a widget needs build](#rebuild-list)) | | ||
| 55 | 54 | ||
| 56 | **Note : You must either provide builder, child or both.** | 55 | **Note : You must either provide builder, child or both.** |
| 57 | 56 | ||
| 57 | +### Rebuild list | ||
| 58 | +Starting from version 5.9.0, ScreenUtilInit won't rebuild the whole widget tree, instead it will mark widget needs build only if: | ||
| 59 | +- Widget is not a flutter widget (widgets are available in [Flutter Docs](https://docs.flutter.dev/reference/widgets)) | ||
| 60 | +- Widget does not start with underscore (`_`) | ||
| 61 | +- Widget does not declare `SU` mixin | ||
| 62 | +- `reponsiveWidgets` does not contains widget name | ||
| 63 | + | ||
| 64 | +If you have a widget that uses the library and doesn't meet these options you can either add `SU` mixin or add widget name in responsiveWidgets list. | ||
| 65 | + | ||
| 58 | ### Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option | 66 | ### Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option |
| 59 | 67 | ||
| 60 | Please set the size of the design draft before use, the width and height of the design draft. | 68 | Please set the size of the design draft before use, the width and height of the design draft. |
| 61 | 69 | ||
| 62 | -#### The first way (You must use it once in your app) | 70 | +#### The first way (You should use it once in your app) |
| 63 | 71 | ||
| 64 | ```dart | 72 | ```dart |
| 65 | void main() => runApp(MyApp()); | 73 | void main() => runApp(MyApp()); |
| @@ -74,7 +82,8 @@ class MyApp extends StatelessWidget { | @@ -74,7 +82,8 @@ class MyApp extends StatelessWidget { | ||
| 74 | designSize: const Size(360, 690), | 82 | designSize: const Size(360, 690), |
| 75 | minTextAdapt: true, | 83 | minTextAdapt: true, |
| 76 | splitScreenMode: true, | 84 | splitScreenMode: true, |
| 77 | - builder: (context , child) { | 85 | + // Use builder only if you need to use library outside ScreenUtilInit context |
| 86 | + builder: (_ , child) { | ||
| 78 | return MaterialApp( | 87 | return MaterialApp( |
| 79 | debugShowCheckedModeBanner: false, | 88 | debugShowCheckedModeBanner: false, |
| 80 | title: 'First Method', | 89 | title: 'First Method', |
| @@ -169,6 +178,8 @@ class _HomePageState extends State<HomePage> { | @@ -169,6 +178,8 @@ class _HomePageState extends State<HomePage> { | ||
| 169 | } | 178 | } |
| 170 | ``` | 179 | ``` |
| 171 | 180 | ||
| 181 | +**Note: calling ScreenUtil.init second time, any non-provided parameter will not be replaced with default value. Use ScreenUtil.configure instead** | ||
| 182 | + | ||
| 172 | ### API | 183 | ### API |
| 173 | 184 | ||
| 174 | #### Pass the dp size of the design draft | 185 | #### Pass the dp size of the design draft |
example/lib/responsive_widgets.g.dart
0 → 100644
| 1 | +///////////////////////////////////////////////////////////////////////// | ||
| 2 | +/// Generated via plugin: flutter_screenutil_generator - Do Not Touch /// | ||
| 3 | +///////////////////////////////////////////////////////////////////////// | ||
| 4 | + | ||
| 5 | +part of 'responsive_widgets.su.dart'; | ||
| 6 | + | ||
| 7 | +const _responsiveWidgets = { | ||
| 8 | + 'MyThemedApp', | ||
| 9 | + 'MyApp', | ||
| 10 | + 'HomePageScaffold', | ||
| 11 | +}; |
example/lib/responsive_widgets.su.dart
0 → 100644
| 1 | +import 'package:example/responsive_widgets.su.dart'; | ||
| 1 | import 'package:example/src/home.dart'; | 2 | import 'package:example/src/home.dart'; |
| 2 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| @@ -9,22 +10,20 @@ class MyApp extends StatelessWidget { | @@ -9,22 +10,20 @@ class MyApp extends StatelessWidget { | ||
| 9 | Widget build(BuildContext context) { | 10 | Widget build(BuildContext context) { |
| 10 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it | 11 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it |
| 11 | return ScreenUtilInit( | 12 | return ScreenUtilInit( |
| 12 | - useInheritedMediaQuery: false, | ||
| 13 | - builder: (_, child) { | ||
| 14 | - return MaterialApp( | ||
| 15 | - debugShowCheckedModeBanner: false, | ||
| 16 | - title: 'First Method', | ||
| 17 | - // You can use the library anywhere in the app even in theme | ||
| 18 | - theme: ThemeData( | ||
| 19 | - primarySwatch: Colors.blue, | ||
| 20 | - textTheme: Typography(platform: TargetPlatform.iOS) | ||
| 21 | - .black | ||
| 22 | - .apply(fontSizeFactor: 1), | ||
| 23 | - ), | ||
| 24 | - home: child, | ||
| 25 | - ); | ||
| 26 | - }, | ||
| 27 | - child: const HomePage(title: 'First Method'), | 13 | + responsiveWidgets: responsiveWidgets, |
| 14 | + ensureScreenSize: true, | ||
| 15 | + child: MaterialApp( | ||
| 16 | + debugShowCheckedModeBanner: false, | ||
| 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: Typography(platform: TargetPlatform.iOS) | ||
| 22 | + .black | ||
| 23 | + .apply(fontSizeFactor: 1), | ||
| 24 | + ), | ||
| 25 | + home: const HomePage(title: 'First Method'), | ||
| 26 | + ), | ||
| 28 | ); | 27 | ); |
| 29 | } | 28 | } |
| 30 | } | 29 | } |
| @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | ||
| 2 | import 'package:flutter/services.dart'; | 2 | import 'package:flutter/services.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | 4 | ||
| 5 | -class HomePageScaffold extends StatelessWidget { | 5 | +class HomePageScaffold extends StatelessWidget with SU { |
| 6 | const HomePageScaffold({Key? key, this.title = ''}) : super(key: key); | 6 | const HomePageScaffold({Key? key, this.title = ''}) : super(key: key); |
| 7 | 7 | ||
| 8 | void printScreenInformation(BuildContext context) { | 8 | void printScreenInformation(BuildContext context) { |
| @@ -43,7 +43,7 @@ void main() { | @@ -43,7 +43,7 @@ void main() { | ||
| 43 | data: currentData, | 43 | data: currentData, |
| 44 | child: ScreenUtilInit( | 44 | child: ScreenUtilInit( |
| 45 | designSize: designSize, | 45 | designSize: designSize, |
| 46 | - builder: (context, child) => MaterialApp( | 46 | + child: MaterialApp( |
| 47 | home: Material( | 47 | home: Material( |
| 48 | child: TextButton( | 48 | child: TextButton( |
| 49 | key: _key, | 49 | key: _key, |
| @@ -68,6 +68,9 @@ void main() { | @@ -68,6 +68,9 @@ void main() { | ||
| 68 | // Tests with initial screen size | 68 | // Tests with initial screen size |
| 69 | testSize(initialSize); | 69 | testSize(initialSize); |
| 70 | 70 | ||
| 71 | + // Wait for FutureBuilder to be resolved | ||
| 72 | + await tester.pumpAndSettle(); | ||
| 73 | + | ||
| 71 | // Click On button to simulate changing screen size | 74 | // Click On button to simulate changing screen size |
| 72 | await tap(); | 75 | await tap(); |
| 73 | // Tests with bigger screen size | 76 | // Tests with bigger screen size |
| @@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" | @@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" | ||
| 60 | // Version | 60 | // Version |
| 61 | // | 61 | // |
| 62 | 62 | ||
| 63 | -#ifdef FLUTTER_BUILD_NUMBER | ||
| 64 | -#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER | 63 | +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) |
| 64 | +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD | ||
| 65 | #else | 65 | #else |
| 66 | -#define VERSION_AS_NUMBER 1,0,0 | 66 | +#define VERSION_AS_NUMBER 1,0,0,0 |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| 69 | -#ifdef FLUTTER_BUILD_NAME | ||
| 70 | -#define VERSION_AS_STRING #FLUTTER_BUILD_NAME | 69 | +#if defined(FLUTTER_VERSION) |
| 70 | +#define VERSION_AS_STRING FLUTTER_VERSION | ||
| 71 | #else | 71 | #else |
| 72 | #define VERSION_AS_STRING "1.0.0" | 72 | #define VERSION_AS_STRING "1.0.0" |
| 73 | #endif | 73 | #endif |
| @@ -10,3 +10,4 @@ export 'src/r_sizedbox.dart'; | @@ -10,3 +10,4 @@ export 'src/r_sizedbox.dart'; | ||
| 10 | export 'src/screen_util.dart'; | 10 | export 'src/screen_util.dart'; |
| 11 | export 'src/screenutil_init.dart'; | 11 | export 'src/screenutil_init.dart'; |
| 12 | export 'src/size_extension.dart'; | 12 | export 'src/size_extension.dart'; |
| 13 | +export 'src/screenutil_mixin.dart'; |
lib/src/_flutter_widgets.dart
0 → 100644
| 1 | +import 'dart:collection'; | ||
| 2 | + | ||
| 3 | +final flutterWidgets = HashSet<String>.from({ | ||
| 4 | + 'AbsorbPointer', | ||
| 5 | + 'Accumulator', | ||
| 6 | + 'Action', | ||
| 7 | + 'ActionDispatcher', | ||
| 8 | + 'ActionListener', | ||
| 9 | + 'Actions', | ||
| 10 | + 'ActivateAction', | ||
| 11 | + 'ActivateIntent', | ||
| 12 | + 'Align', | ||
| 13 | + 'Alignment', | ||
| 14 | + 'AlignmentDirectional', | ||
| 15 | + 'AlignmentGeometry', | ||
| 16 | + 'AlignmentGeometryTween', | ||
| 17 | + 'AlignmentTween', | ||
| 18 | + 'AlignTransition', | ||
| 19 | + 'AlwaysScrollableScrollPhysics', | ||
| 20 | + 'AlwaysStoppedAnimation', | ||
| 21 | + 'AndroidView', | ||
| 22 | + 'AndroidViewSurface', | ||
| 23 | + 'Animatable', | ||
| 24 | + 'AnimatedAlign', | ||
| 25 | + 'AnimatedBuilder', | ||
| 26 | + 'AnimatedContainer', | ||
| 27 | + 'AnimatedCrossFade', | ||
| 28 | + 'AnimatedDefaultTextStyle', | ||
| 29 | + 'AnimatedFractionallySizedBox', | ||
| 30 | + 'AnimatedGrid', | ||
| 31 | + 'AnimatedGridState', | ||
| 32 | + 'AnimatedList', | ||
| 33 | + 'AnimatedListState', | ||
| 34 | + 'AnimatedModalBarrier', | ||
| 35 | + 'AnimatedOpacity', | ||
| 36 | + 'AnimatedPadding', | ||
| 37 | + 'AnimatedPhysicalModel', | ||
| 38 | + 'AnimatedPositioned', | ||
| 39 | + 'AnimatedPositionedDirectional', | ||
| 40 | + 'AnimatedRotation', | ||
| 41 | + 'AnimatedScale', | ||
| 42 | + 'AnimatedSize', | ||
| 43 | + 'AnimatedSlide', | ||
| 44 | + 'AnimatedSwitcher', | ||
| 45 | + 'AnimatedWidget', | ||
| 46 | + 'AnimatedWidgetBaseState', | ||
| 47 | + 'Animation', | ||
| 48 | + 'AnimationController', | ||
| 49 | + 'AnimationMax', | ||
| 50 | + 'AnimationMean', | ||
| 51 | + 'AnimationMin', | ||
| 52 | + 'AnnotatedRegion', | ||
| 53 | + 'AspectRatio', | ||
| 54 | + 'AssetBundle', | ||
| 55 | + 'AssetBundleImageKey', | ||
| 56 | + 'AssetBundleImageProvider', | ||
| 57 | + 'AssetImage', | ||
| 58 | + 'AsyncSnapshot', | ||
| 59 | + 'AutocompleteHighlightedOption', | ||
| 60 | + 'AutocompleteNextOptionIntent', | ||
| 61 | + 'AutocompletePreviousOptionIntent', | ||
| 62 | + 'AutofillGroup', | ||
| 63 | + 'AutofillGroupState', | ||
| 64 | + 'AutofillHints', | ||
| 65 | + 'AutomaticKeepAlive', | ||
| 66 | + 'AutomaticNotchedShape', | ||
| 67 | + 'BackButtonDispatcher', | ||
| 68 | + 'BackButtonListener', | ||
| 69 | + 'BackdropFilter', | ||
| 70 | + 'BallisticScrollActivity', | ||
| 71 | + 'Banner', | ||
| 72 | + 'BannerPainter', | ||
| 73 | + 'Baseline', | ||
| 74 | + 'BaseTapAndDragGestureRecognizer', | ||
| 75 | + 'BeveledRectangleBorder', | ||
| 76 | + 'BlockSemantics', | ||
| 77 | + 'Border', | ||
| 78 | + 'BorderDirectional', | ||
| 79 | + 'BorderRadius', | ||
| 80 | + 'BorderRadiusDirectional', | ||
| 81 | + 'BorderRadiusGeometry', | ||
| 82 | + 'BorderRadiusTween', | ||
| 83 | + 'BorderSide', | ||
| 84 | + 'BorderTween', | ||
| 85 | + 'BottomNavigationBarItem', | ||
| 86 | + 'BouncingScrollPhysics', | ||
| 87 | + 'BouncingScrollSimulation', | ||
| 88 | + 'BoxBorder', | ||
| 89 | + 'BoxConstraints', | ||
| 90 | + 'BoxConstraintsTween', | ||
| 91 | + 'BoxDecoration', | ||
| 92 | + 'BoxPainter', | ||
| 93 | + 'BoxScrollView', | ||
| 94 | + 'BoxShadow', | ||
| 95 | + 'BuildContext', | ||
| 96 | + 'Builder', | ||
| 97 | + 'BuildOwner', | ||
| 98 | + 'ButtonActivateIntent', | ||
| 99 | + 'CallbackAction', | ||
| 100 | + 'CallbackShortcuts', | ||
| 101 | + 'Canvas', | ||
| 102 | + 'CapturedThemes', | ||
| 103 | + 'CatmullRomCurve', | ||
| 104 | + 'CatmullRomSpline', | ||
| 105 | + 'Center', | ||
| 106 | + 'ChangeNotifier', | ||
| 107 | + 'CharacterActivator', | ||
| 108 | + 'CharacterRange', | ||
| 109 | + 'Characters', | ||
| 110 | + 'CheckedModeBanner', | ||
| 111 | + 'ChildBackButtonDispatcher', | ||
| 112 | + 'CircleBorder', | ||
| 113 | + 'CircularNotchedRectangle', | ||
| 114 | + 'ClampingScrollPhysics', | ||
| 115 | + 'ClampingScrollSimulation', | ||
| 116 | + 'ClipboardStatusNotifier', | ||
| 117 | + 'ClipContext', | ||
| 118 | + 'ClipOval', | ||
| 119 | + 'ClipPath', | ||
| 120 | + 'ClipRect', | ||
| 121 | + 'ClipRRect', | ||
| 122 | + 'Color', | ||
| 123 | + 'ColoredBox', | ||
| 124 | + 'ColorFilter', | ||
| 125 | + 'ColorFiltered', | ||
| 126 | + 'ColorProperty', | ||
| 127 | + 'ColorSwatch', | ||
| 128 | + 'ColorTween', | ||
| 129 | + 'Column', | ||
| 130 | + 'ComponentElement', | ||
| 131 | + 'CompositedTransformFollower', | ||
| 132 | + 'CompositedTransformTarget', | ||
| 133 | + 'CompoundAnimation', | ||
| 134 | + 'ConstantTween', | ||
| 135 | + 'ConstrainedBox', | ||
| 136 | + 'ConstrainedLayoutBuilder', | ||
| 137 | + 'ConstraintsTransformBox', | ||
| 138 | + 'Container', | ||
| 139 | + 'ContentInsertionConfiguration', | ||
| 140 | + 'ContextAction', | ||
| 141 | + 'ContextMenuButtonItem', | ||
| 142 | + 'ContextMenuController', | ||
| 143 | + 'ContinuousRectangleBorder', | ||
| 144 | + 'CopySelectionTextIntent', | ||
| 145 | + 'Cubic', | ||
| 146 | + 'Curve', | ||
| 147 | + 'Curve2D', | ||
| 148 | + 'Curve2DSample', | ||
| 149 | + 'CurvedAnimation', | ||
| 150 | + 'Curves', | ||
| 151 | + 'CurveTween', | ||
| 152 | + 'CustomClipper', | ||
| 153 | + 'CustomMultiChildLayout', | ||
| 154 | + 'CustomPaint', | ||
| 155 | + 'CustomPainter', | ||
| 156 | + 'CustomPainterSemantics', | ||
| 157 | + 'CustomScrollView', | ||
| 158 | + 'CustomSingleChildLayout', | ||
| 159 | + 'DebugCreator', | ||
| 160 | + 'DecoratedBox', | ||
| 161 | + 'DecoratedBoxTransition', | ||
| 162 | + 'Decoration', | ||
| 163 | + 'DecorationImage', | ||
| 164 | + 'DecorationImagePainter', | ||
| 165 | + 'DecorationTween', | ||
| 166 | + 'DefaultAssetBundle', | ||
| 167 | + 'DefaultPlatformMenuDelegate', | ||
| 168 | + 'DefaultSelectionStyle', | ||
| 169 | + 'DefaultTextEditingShortcuts', | ||
| 170 | + 'DefaultTextHeightBehavior', | ||
| 171 | + 'DefaultTextStyle', | ||
| 172 | + 'DefaultTextStyleTransition', | ||
| 173 | + 'DefaultTransitionDelegate', | ||
| 174 | + 'DefaultWidgetsLocalizations', | ||
| 175 | + 'DeleteCharacterIntent', | ||
| 176 | + 'DeleteToLineBreakIntent', | ||
| 177 | + 'DeleteToNextWordBoundaryIntent', | ||
| 178 | + 'DesktopTextSelectionToolbarLayoutDelegate', | ||
| 179 | + 'DevToolsDeepLinkProperty', | ||
| 180 | + 'DiagnosticsNode', | ||
| 181 | + 'DirectionalCaretMovementIntent', | ||
| 182 | + 'DirectionalFocusAction', | ||
| 183 | + 'DirectionalFocusIntent', | ||
| 184 | + 'Directionality', | ||
| 185 | + 'DirectionalTextEditingIntent', | ||
| 186 | + 'DismissAction', | ||
| 187 | + 'Dismissible', | ||
| 188 | + 'DismissIntent', | ||
| 189 | + 'DismissUpdateDetails', | ||
| 190 | + 'DisplayFeatureSubScreen', | ||
| 191 | + 'DisposableBuildContext', | ||
| 192 | + 'DoNothingAction', | ||
| 193 | + 'DoNothingAndStopPropagationIntent', | ||
| 194 | + 'DoNothingAndStopPropagationTextIntent', | ||
| 195 | + 'DoNothingIntent', | ||
| 196 | + 'DragDownDetails', | ||
| 197 | + 'DragEndDetails', | ||
| 198 | + 'Draggable', | ||
| 199 | + 'DraggableDetails', | ||
| 200 | + 'DraggableScrollableActuator', | ||
| 201 | + 'DraggableScrollableController', | ||
| 202 | + 'DraggableScrollableNotification', | ||
| 203 | + 'DraggableScrollableSheet', | ||
| 204 | + 'DragScrollActivity', | ||
| 205 | + 'DragStartDetails', | ||
| 206 | + 'DragTarget', | ||
| 207 | + 'DragTargetDetails', | ||
| 208 | + 'DragUpdateDetails', | ||
| 209 | + 'DrivenScrollActivity', | ||
| 210 | + 'DualTransitionBuilder', | ||
| 211 | + 'EdgeDraggingAutoScroller', | ||
| 212 | + 'EdgeInsets', | ||
| 213 | + 'EdgeInsetsDirectional', | ||
| 214 | + 'EdgeInsetsGeometry', | ||
| 215 | + 'EdgeInsetsGeometryTween', | ||
| 216 | + 'EdgeInsetsTween', | ||
| 217 | + 'EditableText', | ||
| 218 | + 'EditableTextState', | ||
| 219 | + 'ElasticInCurve', | ||
| 220 | + 'ElasticInOutCurve', | ||
| 221 | + 'ElasticOutCurve', | ||
| 222 | + 'Element', | ||
| 223 | + 'EmptyTextSelectionControls', | ||
| 224 | + 'ErrorDescription', | ||
| 225 | + 'ErrorHint', | ||
| 226 | + 'ErrorSummary', | ||
| 227 | + 'ErrorWidget', | ||
| 228 | + 'ExactAssetImage', | ||
| 229 | + 'ExcludeFocus', | ||
| 230 | + 'ExcludeFocusTraversal', | ||
| 231 | + 'ExcludeSemantics', | ||
| 232 | + 'Expanded', | ||
| 233 | + 'ExpandSelectionToDocumentBoundaryIntent', | ||
| 234 | + 'ExpandSelectionToLineBreakIntent', | ||
| 235 | + 'ExtendSelectionByCharacterIntent', | ||
| 236 | + 'ExtendSelectionByPageIntent', | ||
| 237 | + 'ExtendSelectionToDocumentBoundaryIntent', | ||
| 238 | + 'ExtendSelectionToLineBreakIntent', | ||
| 239 | + 'ExtendSelectionToNextParagraphBoundaryIntent', | ||
| 240 | + 'ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent', | ||
| 241 | + 'ExtendSelectionToNextWordBoundaryIntent', | ||
| 242 | + 'ExtendSelectionToNextWordBoundaryOrCaretLocationIntent', | ||
| 243 | + 'ExtendSelectionVerticallyToAdjacentLineIntent', | ||
| 244 | + 'ExtendSelectionVerticallyToAdjacentPageIntent', | ||
| 245 | + 'FadeInImage', | ||
| 246 | + 'FadeTransition', | ||
| 247 | + 'FileImage', | ||
| 248 | + 'FittedBox', | ||
| 249 | + 'FittedSizes', | ||
| 250 | + 'FixedColumnWidth', | ||
| 251 | + 'FixedExtentMetrics', | ||
| 252 | + 'FixedExtentScrollController', | ||
| 253 | + 'FixedExtentScrollPhysics', | ||
| 254 | + 'FixedScrollMetrics', | ||
| 255 | + 'Flex', | ||
| 256 | + 'FlexColumnWidth', | ||
| 257 | + 'Flexible', | ||
| 258 | + 'FlippedCurve', | ||
| 259 | + 'FlippedTweenSequence', | ||
| 260 | + 'Flow', | ||
| 261 | + 'FlowDelegate', | ||
| 262 | + 'FlowPaintingContext', | ||
| 263 | + 'FlutterErrorDetails', | ||
| 264 | + 'FlutterLogoDecoration', | ||
| 265 | + 'Focus', | ||
| 266 | + 'FocusableActionDetector', | ||
| 267 | + 'FocusAttachment', | ||
| 268 | + 'FocusManager', | ||
| 269 | + 'FocusNode', | ||
| 270 | + 'FocusOrder', | ||
| 271 | + 'FocusScope', | ||
| 272 | + 'FocusScopeNode', | ||
| 273 | + 'FocusTraversalGroup', | ||
| 274 | + 'FocusTraversalOrder', | ||
| 275 | + 'FocusTraversalPolicy', | ||
| 276 | + 'FontWeight', | ||
| 277 | + 'ForcePressDetails', | ||
| 278 | + 'Form', | ||
| 279 | + 'FormField', | ||
| 280 | + 'FormFieldState', | ||
| 281 | + 'FormState', | ||
| 282 | + 'FractionallySizedBox', | ||
| 283 | + 'FractionalOffset', | ||
| 284 | + 'FractionalOffsetTween', | ||
| 285 | + 'FractionalTranslation', | ||
| 286 | + 'FractionColumnWidth', | ||
| 287 | + 'FutureBuilder', | ||
| 288 | + 'GestureDetector', | ||
| 289 | + 'GestureRecognizerFactory', | ||
| 290 | + 'GestureRecognizerFactoryWithHandlers', | ||
| 291 | + 'GlobalKey', | ||
| 292 | + 'GlobalObjectKey', | ||
| 293 | + 'GlowingOverscrollIndicator', | ||
| 294 | + 'Gradient', | ||
| 295 | + 'GradientRotation', | ||
| 296 | + 'GradientTransform', | ||
| 297 | + 'GridPaper', | ||
| 298 | + 'GridView', | ||
| 299 | + 'Hero', | ||
| 300 | + 'HeroController', | ||
| 301 | + 'HeroControllerScope', | ||
| 302 | + 'HeroMode', | ||
| 303 | + 'HoldScrollActivity', | ||
| 304 | + 'HSLColor', | ||
| 305 | + 'HSVColor', | ||
| 306 | + 'HtmlElementView', | ||
| 307 | + 'Icon', | ||
| 308 | + 'IconData', | ||
| 309 | + 'IconDataProperty', | ||
| 310 | + 'IconTheme', | ||
| 311 | + 'IconThemeData', | ||
| 312 | + 'IdleScrollActivity', | ||
| 313 | + 'IgnorePointer', | ||
| 314 | + 'Image', | ||
| 315 | + 'ImageCache', | ||
| 316 | + 'ImageCacheStatus', | ||
| 317 | + 'ImageChunkEvent', | ||
| 318 | + 'ImageConfiguration', | ||
| 319 | + 'ImageFiltered', | ||
| 320 | + 'ImageIcon', | ||
| 321 | + 'ImageInfo', | ||
| 322 | + 'ImageProvider', | ||
| 323 | + 'ImageShader', | ||
| 324 | + 'ImageSizeInfo', | ||
| 325 | + 'ImageStream', | ||
| 326 | + 'ImageStreamCompleter', | ||
| 327 | + 'ImageStreamCompleterHandle', | ||
| 328 | + 'ImageStreamListener', | ||
| 329 | + 'ImageTilingInfo', | ||
| 330 | + 'ImplicitlyAnimatedWidget', | ||
| 331 | + 'ImplicitlyAnimatedWidgetState', | ||
| 332 | + 'IndexedSemantics', | ||
| 333 | + 'IndexedSlot', | ||
| 334 | + 'IndexedStack', | ||
| 335 | + 'InheritedElement', | ||
| 336 | + 'InheritedModel', | ||
| 337 | + 'InheritedModelElement', | ||
| 338 | + 'InheritedNotifier', | ||
| 339 | + 'InheritedTheme', | ||
| 340 | + 'InheritedWidget', | ||
| 341 | + 'InlineSpan', | ||
| 342 | + 'InlineSpanSemanticsInformation', | ||
| 343 | + 'InspectorSelection', | ||
| 344 | + 'InspectorSerializationDelegate', | ||
| 345 | + 'Intent', | ||
| 346 | + 'InteractiveViewer', | ||
| 347 | + 'Interval', | ||
| 348 | + 'IntrinsicColumnWidth', | ||
| 349 | + 'IntrinsicHeight', | ||
| 350 | + 'IntrinsicWidth', | ||
| 351 | + 'IntTween', | ||
| 352 | + 'KeepAlive', | ||
| 353 | + 'KeepAliveHandle', | ||
| 354 | + 'KeepAliveNotification', | ||
| 355 | + 'Key', | ||
| 356 | + 'KeyboardInsertedContent', | ||
| 357 | + 'KeyboardListener', | ||
| 358 | + 'KeyedSubtree', | ||
| 359 | + 'KeyEvent', | ||
| 360 | + 'KeySet', | ||
| 361 | + 'LabeledGlobalKey', | ||
| 362 | + 'LayerLink', | ||
| 363 | + 'LayoutBuilder', | ||
| 364 | + 'LayoutChangedNotification', | ||
| 365 | + 'LayoutId', | ||
| 366 | + 'LeafRenderObjectElement', | ||
| 367 | + 'LeafRenderObjectWidget', | ||
| 368 | + 'LexicalFocusOrder', | ||
| 369 | + 'LimitedBox', | ||
| 370 | + 'LinearBorder', | ||
| 371 | + 'LinearBorderEdge', | ||
| 372 | + 'LinearGradient', | ||
| 373 | + 'ListBody', | ||
| 374 | + 'Listenable', | ||
| 375 | + 'ListenableBuilder', | ||
| 376 | + 'Listener', | ||
| 377 | + 'ListView', | ||
| 378 | + 'ListWheelChildBuilderDelegate', | ||
| 379 | + 'ListWheelChildDelegate', | ||
| 380 | + 'ListWheelChildListDelegate', | ||
| 381 | + 'ListWheelChildLoopingListDelegate', | ||
| 382 | + 'ListWheelElement', | ||
| 383 | + 'ListWheelScrollView', | ||
| 384 | + 'ListWheelViewport', | ||
| 385 | + 'Locale', | ||
| 386 | + 'LocalHistoryEntry', | ||
| 387 | + 'Localizations', | ||
| 388 | + 'LocalizationsDelegate', | ||
| 389 | + 'LocalKey', | ||
| 390 | + 'LogicalKeySet', | ||
| 391 | + 'LongPressDraggable', | ||
| 392 | + 'LongPressEndDetails', | ||
| 393 | + 'LongPressMoveUpdateDetails', | ||
| 394 | + 'LongPressStartDetails', | ||
| 395 | + 'LookupBoundary', | ||
| 396 | + 'MagnifierController', | ||
| 397 | + 'MagnifierDecoration', | ||
| 398 | + 'MagnifierInfo', | ||
| 399 | + 'MaskFilter', | ||
| 400 | + 'Matrix4', | ||
| 401 | + 'Matrix4Tween', | ||
| 402 | + 'MatrixUtils', | ||
| 403 | + 'MaxColumnWidth', | ||
| 404 | + 'MediaQuery', | ||
| 405 | + 'MediaQueryData', | ||
| 406 | + 'MemoryImage', | ||
| 407 | + 'MergeSemantics', | ||
| 408 | + 'MetaData', | ||
| 409 | + 'MinColumnWidth', | ||
| 410 | + 'ModalBarrier', | ||
| 411 | + 'ModalRoute', | ||
| 412 | + 'MouseCursor', | ||
| 413 | + 'MouseRegion', | ||
| 414 | + 'MultiChildLayoutDelegate', | ||
| 415 | + 'MultiChildRenderObjectElement', | ||
| 416 | + 'MultiChildRenderObjectWidget', | ||
| 417 | + 'MultiFrameImageStreamCompleter', | ||
| 418 | + 'MultiSelectableSelectionContainerDelegate', | ||
| 419 | + 'NavigationToolbar', | ||
| 420 | + 'Navigator', | ||
| 421 | + 'NavigatorObserver', | ||
| 422 | + 'NavigatorState', | ||
| 423 | + 'NestedScrollView', | ||
| 424 | + 'NestedScrollViewState', | ||
| 425 | + 'NestedScrollViewViewport', | ||
| 426 | + 'NetworkImage', | ||
| 427 | + 'NeverScrollableScrollPhysics', | ||
| 428 | + 'NextFocusAction', | ||
| 429 | + 'NextFocusIntent', | ||
| 430 | + 'NotchedShape', | ||
| 431 | + 'Notification', | ||
| 432 | + 'NotificationListener', | ||
| 433 | + 'NumericFocusOrder', | ||
| 434 | + 'ObjectKey', | ||
| 435 | + 'Offset', | ||
| 436 | + 'Offstage', | ||
| 437 | + 'OneFrameImageStreamCompleter', | ||
| 438 | + 'Opacity', | ||
| 439 | + 'OrderedTraversalPolicy', | ||
| 440 | + 'OrientationBuilder', | ||
| 441 | + 'OutlinedBorder', | ||
| 442 | + 'OvalBorder', | ||
| 443 | + 'OverflowBar', | ||
| 444 | + 'OverflowBox', | ||
| 445 | + 'Overlay', | ||
| 446 | + 'OverlayEntry', | ||
| 447 | + 'OverlayPortal', | ||
| 448 | + 'OverlayPortalController', | ||
| 449 | + 'OverlayRoute', | ||
| 450 | + 'OverlayState', | ||
| 451 | + 'OverscrollIndicatorNotification', | ||
| 452 | + 'OverscrollNotification', | ||
| 453 | + 'Padding', | ||
| 454 | + 'Page', | ||
| 455 | + 'PageController', | ||
| 456 | + 'PageMetrics', | ||
| 457 | + 'PageRoute', | ||
| 458 | + 'PageRouteBuilder', | ||
| 459 | + 'PageScrollPhysics', | ||
| 460 | + 'PageStorage', | ||
| 461 | + 'PageStorageBucket', | ||
| 462 | + 'PageStorageKey', | ||
| 463 | + 'PageView', | ||
| 464 | + 'Paint', | ||
| 465 | + 'PaintingContext', | ||
| 466 | + 'ParametricCurve', | ||
| 467 | + 'ParentDataElement', | ||
| 468 | + 'ParentDataWidget', | ||
| 469 | + 'PasteTextIntent', | ||
| 470 | + 'Path', | ||
| 471 | + 'PerformanceOverlay', | ||
| 472 | + 'PhysicalModel', | ||
| 473 | + 'PhysicalShape', | ||
| 474 | + 'Placeholder', | ||
| 475 | + 'PlaceholderDimensions', | ||
| 476 | + 'PlaceholderSpan', | ||
| 477 | + 'PlatformMenu', | ||
| 478 | + 'PlatformMenuBar', | ||
| 479 | + 'PlatformMenuDelegate', | ||
| 480 | + 'PlatformMenuItem', | ||
| 481 | + 'PlatformMenuItemGroup', | ||
| 482 | + 'PlatformProvidedMenuItem', | ||
| 483 | + 'PlatformRouteInformationProvider', | ||
| 484 | + 'PlatformSelectableRegionContextMenu', | ||
| 485 | + 'PlatformViewCreationParams', | ||
| 486 | + 'PlatformViewLink', | ||
| 487 | + 'PlatformViewSurface', | ||
| 488 | + 'PointerCancelEvent', | ||
| 489 | + 'PointerDownEvent', | ||
| 490 | + 'PointerEvent', | ||
| 491 | + 'PointerMoveEvent', | ||
| 492 | + 'PointerUpEvent', | ||
| 493 | + 'PopupRoute', | ||
| 494 | + 'Positioned', | ||
| 495 | + 'PositionedDirectional', | ||
| 496 | + 'PositionedTransition', | ||
| 497 | + 'PreferredSize', | ||
| 498 | + 'PreferredSizeWidget', | ||
| 499 | + 'PreviousFocusAction', | ||
| 500 | + 'PreviousFocusIntent', | ||
| 501 | + 'PrimaryScrollController', | ||
| 502 | + 'PrioritizedAction', | ||
| 503 | + 'PrioritizedIntents', | ||
| 504 | + 'ProxyAnimation', | ||
| 505 | + 'ProxyElement', | ||
| 506 | + 'ProxyWidget', | ||
| 507 | + 'RadialGradient', | ||
| 508 | + 'Radius', | ||
| 509 | + 'RangeMaintainingScrollPhysics', | ||
| 510 | + 'RawAutocomplete', | ||
| 511 | + 'RawDialogRoute', | ||
| 512 | + 'RawGestureDetector', | ||
| 513 | + 'RawGestureDetectorState', | ||
| 514 | + 'RawImage', | ||
| 515 | + 'RawKeyboardListener', | ||
| 516 | + 'RawKeyEvent', | ||
| 517 | + 'RawMagnifier', | ||
| 518 | + 'RawScrollbar', | ||
| 519 | + 'RawScrollbarState', | ||
| 520 | + 'ReadingOrderTraversalPolicy', | ||
| 521 | + 'Rect', | ||
| 522 | + 'RectTween', | ||
| 523 | + 'RedoTextIntent', | ||
| 524 | + 'RelativePositionedTransition', | ||
| 525 | + 'RelativeRect', | ||
| 526 | + 'RelativeRectTween', | ||
| 527 | + 'RenderBox', | ||
| 528 | + 'RenderNestedScrollViewViewport', | ||
| 529 | + 'RenderObject', | ||
| 530 | + 'RenderObjectElement', | ||
| 531 | + 'RenderObjectToWidgetAdapter', | ||
| 532 | + 'RenderObjectToWidgetElement', | ||
| 533 | + 'RenderObjectWidget', | ||
| 534 | + 'RenderSemanticsGestureHandler', | ||
| 535 | + 'RenderSliverOverlapAbsorber', | ||
| 536 | + 'RenderSliverOverlapInjector', | ||
| 537 | + 'RenderTapRegion', | ||
| 538 | + 'RenderTapRegionSurface', | ||
| 539 | + 'ReorderableDelayedDragStartListener', | ||
| 540 | + 'ReorderableDragStartListener', | ||
| 541 | + 'ReorderableList', | ||
| 542 | + 'ReorderableListState', | ||
| 543 | + 'RepaintBoundary', | ||
| 544 | + 'ReplaceTextIntent', | ||
| 545 | + 'RequestFocusAction', | ||
| 546 | + 'RequestFocusIntent', | ||
| 547 | + 'ResizeImage', | ||
| 548 | + 'ResizeImageKey', | ||
| 549 | + 'RestorableBool', | ||
| 550 | + 'RestorableBoolN', | ||
| 551 | + 'RestorableChangeNotifier', | ||
| 552 | + 'RestorableDateTime', | ||
| 553 | + 'RestorableDateTimeN', | ||
| 554 | + 'RestorableDouble', | ||
| 555 | + 'RestorableDoubleN', | ||
| 556 | + 'RestorableEnum', | ||
| 557 | + 'RestorableEnumN', | ||
| 558 | + 'RestorableInt', | ||
| 559 | + 'RestorableIntN', | ||
| 560 | + 'RestorableListenable', | ||
| 561 | + 'RestorableNum', | ||
| 562 | + 'RestorableNumN', | ||
| 563 | + 'RestorableProperty', | ||
| 564 | + 'RestorableRouteFuture', | ||
| 565 | + 'RestorableString', | ||
| 566 | + 'RestorableStringN', | ||
| 567 | + 'RestorableTextEditingController', | ||
| 568 | + 'RestorableValue', | ||
| 569 | + 'RestorationBucket', | ||
| 570 | + 'RestorationScope', | ||
| 571 | + 'ReverseAnimation', | ||
| 572 | + 'ReverseTween', | ||
| 573 | + 'RichText', | ||
| 574 | + 'RootBackButtonDispatcher', | ||
| 575 | + 'RootRenderObjectElement', | ||
| 576 | + 'RootRestorationScope', | ||
| 577 | + 'RotatedBox', | ||
| 578 | + 'RotationTransition', | ||
| 579 | + 'RoundedRectangleBorder', | ||
| 580 | + 'Route', | ||
| 581 | + 'RouteAware', | ||
| 582 | + 'RouteInformation', | ||
| 583 | + 'RouteInformationParser', | ||
| 584 | + 'RouteInformationProvider', | ||
| 585 | + 'RouteObserver', | ||
| 586 | + 'Router', | ||
| 587 | + 'RouterConfig', | ||
| 588 | + 'RouterDelegate', | ||
| 589 | + 'RouteSettings', | ||
| 590 | + 'RouteTransitionRecord', | ||
| 591 | + 'Row', | ||
| 592 | + 'RRect', | ||
| 593 | + 'RSTransform', | ||
| 594 | + 'SafeArea', | ||
| 595 | + 'SawTooth', | ||
| 596 | + 'ScaleEndDetails', | ||
| 597 | + 'ScaleStartDetails', | ||
| 598 | + 'ScaleTransition', | ||
| 599 | + 'ScaleUpdateDetails', | ||
| 600 | + 'Scrollable', | ||
| 601 | + 'ScrollableDetails', | ||
| 602 | + 'ScrollableState', | ||
| 603 | + 'ScrollAction', | ||
| 604 | + 'ScrollActivity', | ||
| 605 | + 'ScrollActivityDelegate', | ||
| 606 | + 'ScrollAwareImageProvider', | ||
| 607 | + 'ScrollbarPainter', | ||
| 608 | + 'ScrollBehavior', | ||
| 609 | + 'ScrollConfiguration', | ||
| 610 | + 'ScrollContext', | ||
| 611 | + 'ScrollController', | ||
| 612 | + 'ScrollDragController', | ||
| 613 | + 'ScrollEndNotification', | ||
| 614 | + 'ScrollHoldController', | ||
| 615 | + 'ScrollIncrementDetails', | ||
| 616 | + 'ScrollIntent', | ||
| 617 | + 'ScrollMetricsNotification', | ||
| 618 | + 'ScrollNotification', | ||
| 619 | + 'ScrollNotificationObserver', | ||
| 620 | + 'ScrollNotificationObserverState', | ||
| 621 | + 'ScrollPhysics', | ||
| 622 | + 'ScrollPosition', | ||
| 623 | + 'ScrollPositionWithSingleContext', | ||
| 624 | + 'ScrollSpringSimulation', | ||
| 625 | + 'ScrollStartNotification', | ||
| 626 | + 'ScrollToDocumentBoundaryIntent', | ||
| 627 | + 'ScrollUpdateNotification', | ||
| 628 | + 'ScrollView', | ||
| 629 | + 'SelectableRegion', | ||
| 630 | + 'SelectableRegionState', | ||
| 631 | + 'SelectAction', | ||
| 632 | + 'SelectAllTextIntent', | ||
| 633 | + 'SelectIntent', | ||
| 634 | + 'SelectionContainer', | ||
| 635 | + 'SelectionContainerDelegate', | ||
| 636 | + 'SelectionOverlay', | ||
| 637 | + 'SelectionRegistrarScope', | ||
| 638 | + 'Semantics', | ||
| 639 | + 'SemanticsDebugger', | ||
| 640 | + 'SemanticsGestureDelegate', | ||
| 641 | + 'Shader', | ||
| 642 | + 'ShaderMask', | ||
| 643 | + 'ShaderWarmUp', | ||
| 644 | + 'Shadow', | ||
| 645 | + 'ShapeBorder', | ||
| 646 | + 'ShapeBorderClipper', | ||
| 647 | + 'ShapeDecoration', | ||
| 648 | + 'SharedAppData', | ||
| 649 | + 'ShortcutActivator', | ||
| 650 | + 'ShortcutManager', | ||
| 651 | + 'ShortcutMapProperty', | ||
| 652 | + 'ShortcutRegistrar', | ||
| 653 | + 'ShortcutRegistry', | ||
| 654 | + 'ShortcutRegistryEntry', | ||
| 655 | + 'Shortcuts', | ||
| 656 | + 'ShortcutSerialization', | ||
| 657 | + 'ShrinkWrappingViewport', | ||
| 658 | + 'Simulation', | ||
| 659 | + 'SingleActivator', | ||
| 660 | + 'SingleChildLayoutDelegate', | ||
| 661 | + 'SingleChildRenderObjectElement', | ||
| 662 | + 'SingleChildRenderObjectWidget', | ||
| 663 | + 'SingleChildScrollView', | ||
| 664 | + 'Size', | ||
| 665 | + 'SizeChangedLayoutNotification', | ||
| 666 | + 'SizeChangedLayoutNotifier', | ||
| 667 | + 'SizedBox', | ||
| 668 | + 'SizedOverflowBox', | ||
| 669 | + 'SizeTransition', | ||
| 670 | + 'SizeTween', | ||
| 671 | + 'SlideTransition', | ||
| 672 | + 'SliverAnimatedGrid', | ||
| 673 | + 'SliverAnimatedGridState', | ||
| 674 | + 'SliverAnimatedList', | ||
| 675 | + 'SliverAnimatedListState', | ||
| 676 | + 'SliverAnimatedOpacity', | ||
| 677 | + 'SliverChildBuilderDelegate', | ||
| 678 | + 'SliverChildDelegate', | ||
| 679 | + 'SliverChildListDelegate', | ||
| 680 | + 'SliverFadeTransition', | ||
| 681 | + 'SliverFillRemaining', | ||
| 682 | + 'SliverFillViewport', | ||
| 683 | + 'SliverFixedExtentList', | ||
| 684 | + 'SliverGrid', | ||
| 685 | + 'SliverGridDelegate', | ||
| 686 | + 'SliverGridDelegateWithFixedCrossAxisCount', | ||
| 687 | + 'SliverGridDelegateWithMaxCrossAxisExtent', | ||
| 688 | + 'SliverIgnorePointer', | ||
| 689 | + 'SliverLayoutBuilder', | ||
| 690 | + 'SliverList', | ||
| 691 | + 'SliverMultiBoxAdaptorElement', | ||
| 692 | + 'SliverMultiBoxAdaptorWidget', | ||
| 693 | + 'SliverOffstage', | ||
| 694 | + 'SliverOpacity', | ||
| 695 | + 'SliverOverlapAbsorber', | ||
| 696 | + 'SliverOverlapAbsorberHandle', | ||
| 697 | + 'SliverOverlapInjector', | ||
| 698 | + 'SliverPadding', | ||
| 699 | + 'SliverPersistentHeader', | ||
| 700 | + 'SliverPersistentHeaderDelegate', | ||
| 701 | + 'SliverPrototypeExtentList', | ||
| 702 | + 'SliverReorderableList', | ||
| 703 | + 'SliverReorderableListState', | ||
| 704 | + 'SliverSafeArea', | ||
| 705 | + 'SliverToBoxAdapter', | ||
| 706 | + 'SliverVisibility', | ||
| 707 | + 'SliverWithKeepAliveWidget', | ||
| 708 | + 'SlottedRenderObjectElement', | ||
| 709 | + 'SnapshotController', | ||
| 710 | + 'SnapshotPainter', | ||
| 711 | + 'SnapshotWidget', | ||
| 712 | + 'Spacer', | ||
| 713 | + 'SpellCheckConfiguration', | ||
| 714 | + 'SpringDescription', | ||
| 715 | + 'Stack', | ||
| 716 | + 'StadiumBorder', | ||
| 717 | + 'StarBorder', | ||
| 718 | + 'State', | ||
| 719 | + 'StatefulBuilder', | ||
| 720 | + 'StatefulElement', | ||
| 721 | + 'StatefulWidget', | ||
| 722 | + 'StatelessElement', | ||
| 723 | + 'StatelessWidget', | ||
| 724 | + 'StatusTransitionWidget', | ||
| 725 | + 'StepTween', | ||
| 726 | + 'StreamBuilder', | ||
| 727 | + 'StreamBuilderBase', | ||
| 728 | + 'StretchingOverscrollIndicator', | ||
| 729 | + 'StrutStyle', | ||
| 730 | + 'SweepGradient', | ||
| 731 | + 'SystemMouseCursors', | ||
| 732 | + 'Table', | ||
| 733 | + 'TableBorder', | ||
| 734 | + 'TableCell', | ||
| 735 | + 'TableColumnWidth', | ||
| 736 | + 'TableRow', | ||
| 737 | + 'TapAndDragGestureRecognizer', | ||
| 738 | + 'TapAndHorizontalDragGestureRecognizer', | ||
| 739 | + 'TapAndPanGestureRecognizer', | ||
| 740 | + 'TapDownDetails', | ||
| 741 | + 'TapDragDownDetails', | ||
| 742 | + 'TapDragEndDetails', | ||
| 743 | + 'TapDragStartDetails', | ||
| 744 | + 'TapDragUpdateDetails', | ||
| 745 | + 'TapDragUpDetails', | ||
| 746 | + 'TapRegion', | ||
| 747 | + 'TapRegionRegistry', | ||
| 748 | + 'TapRegionSurface', | ||
| 749 | + 'TapUpDetails', | ||
| 750 | + 'Text', | ||
| 751 | + 'TextAlignVertical', | ||
| 752 | + 'TextBox', | ||
| 753 | + 'TextDecoration', | ||
| 754 | + 'TextEditingController', | ||
| 755 | + 'TextEditingValue', | ||
| 756 | + 'TextFieldTapRegion', | ||
| 757 | + 'TextHeightBehavior', | ||
| 758 | + 'TextInputType', | ||
| 759 | + 'TextMagnifierConfiguration', | ||
| 760 | + 'TextPainter', | ||
| 761 | + 'TextPosition', | ||
| 762 | + 'TextRange', | ||
| 763 | + 'TextSelection', | ||
| 764 | + 'TextSelectionControls', | ||
| 765 | + 'TextSelectionGestureDetector', | ||
| 766 | + 'TextSelectionGestureDetectorBuilder', | ||
| 767 | + 'TextSelectionGestureDetectorBuilderDelegate', | ||
| 768 | + 'TextSelectionOverlay', | ||
| 769 | + 'TextSelectionPoint', | ||
| 770 | + 'TextSelectionToolbarAnchors', | ||
| 771 | + 'TextSelectionToolbarLayoutDelegate', | ||
| 772 | + 'TextSpan', | ||
| 773 | + 'TextStyle', | ||
| 774 | + 'TextStyleTween', | ||
| 775 | + 'Texture', | ||
| 776 | + 'ThreePointCubic', | ||
| 777 | + 'Threshold', | ||
| 778 | + 'TickerFuture', | ||
| 779 | + 'TickerMode', | ||
| 780 | + 'TickerProvider', | ||
| 781 | + 'Title', | ||
| 782 | + 'Tolerance', | ||
| 783 | + 'ToolbarItemsParentData', | ||
| 784 | + 'ToolbarOptions', | ||
| 785 | + 'TrackingScrollController', | ||
| 786 | + 'TrainHoppingAnimation', | ||
| 787 | + 'Transform', | ||
| 788 | + 'TransformationController', | ||
| 789 | + 'TransformProperty', | ||
| 790 | + 'TransitionDelegate', | ||
| 791 | + 'TransitionRoute', | ||
| 792 | + 'TransposeCharactersIntent', | ||
| 793 | + 'Tween', | ||
| 794 | + 'TweenAnimationBuilder', | ||
| 795 | + 'TweenSequence', | ||
| 796 | + 'TweenSequenceItem', | ||
| 797 | + 'UiKitView', | ||
| 798 | + 'UnconstrainedBox', | ||
| 799 | + 'UndoHistory', | ||
| 800 | + 'UndoHistoryController', | ||
| 801 | + 'UndoHistoryState', | ||
| 802 | + 'UndoHistoryValue', | ||
| 803 | + 'UndoTextIntent', | ||
| 804 | + 'UniqueKey', | ||
| 805 | + 'UniqueWidget', | ||
| 806 | + 'UnmanagedRestorationScope', | ||
| 807 | + 'UpdateSelectionIntent', | ||
| 808 | + 'UserScrollNotification', | ||
| 809 | + 'ValueKey', | ||
| 810 | + 'ValueListenableBuilder', | ||
| 811 | + 'ValueNotifier', | ||
| 812 | + 'Velocity', | ||
| 813 | + 'View', | ||
| 814 | + 'Viewport', | ||
| 815 | + 'Visibility', | ||
| 816 | + 'VoidCallbackAction', | ||
| 817 | + 'VoidCallbackIntent', | ||
| 818 | + 'Widget', | ||
| 819 | + 'WidgetInspector', | ||
| 820 | + 'WidgetOrderTraversalPolicy', | ||
| 821 | + 'WidgetsApp', | ||
| 822 | + 'WidgetsBindingObserver', | ||
| 823 | + 'WidgetsFlutterBinding', | ||
| 824 | + 'WidgetsLocalizations', | ||
| 825 | + 'WidgetSpan', | ||
| 826 | + 'WidgetToRenderBoxAdapter', | ||
| 827 | + 'WillPopScope', | ||
| 828 | + 'WordBoundary', | ||
| 829 | + 'Wrap' | ||
| 830 | +}); |
| @@ -4,11 +4,12 @@ | @@ -4,11 +4,12 @@ | ||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | import 'dart:math' show min, max; | 6 | import 'dart:math' show min, max; |
| 7 | -import 'dart:ui' show FlutterView; | ||
| 8 | -import 'dart:async' show Completer; | 7 | +import 'dart:ui' as ui show FlutterView; |
| 9 | 8 | ||
| 10 | import 'package:flutter/widgets.dart'; | 9 | import 'package:flutter/widgets.dart'; |
| 11 | 10 | ||
| 11 | +typedef FontSizeResolver = double Function(num fontSize, ScreenUtil instance); | ||
| 12 | + | ||
| 12 | class ScreenUtil { | 13 | class ScreenUtil { |
| 13 | static const Size defaultSize = Size(360, 690); | 14 | static const Size defaultSize = Size(360, 690); |
| 14 | static ScreenUtil _instance = ScreenUtil._(); | 15 | static ScreenUtil _instance = ScreenUtil._(); |
| @@ -20,17 +21,14 @@ class ScreenUtil { | @@ -20,17 +21,14 @@ class ScreenUtil { | ||
| 20 | ///屏幕方向 | 21 | ///屏幕方向 |
| 21 | late Orientation _orientation; | 22 | late Orientation _orientation; |
| 22 | 23 | ||
| 23 | - late double _screenWidth; | ||
| 24 | - late double _screenHeight; | ||
| 25 | late bool _minTextAdapt; | 24 | late bool _minTextAdapt; |
| 26 | - BuildContext? _context; | 25 | + late MediaQueryData _data; |
| 27 | late bool _splitScreenMode; | 26 | late bool _splitScreenMode; |
| 27 | + FontSizeResolver? fontSizeResolver; | ||
| 28 | 28 | ||
| 29 | ScreenUtil._(); | 29 | ScreenUtil._(); |
| 30 | 30 | ||
| 31 | - factory ScreenUtil() { | ||
| 32 | - return _instance; | ||
| 33 | - } | 31 | + factory ScreenUtil() => _instance; |
| 34 | 32 | ||
| 35 | /// Manually wait for window size to be initialized | 33 | /// Manually wait for window size to be initialized |
| 36 | /// | 34 | /// |
| @@ -55,19 +53,25 @@ class ScreenUtil { | @@ -55,19 +53,25 @@ class ScreenUtil { | ||
| 55 | /// ) | 53 | /// ) |
| 56 | /// ``` | 54 | /// ``` |
| 57 | static Future<void> ensureScreenSize([ | 55 | static Future<void> ensureScreenSize([ |
| 58 | - FlutterView? window, | 56 | + ui.FlutterView? window, |
| 59 | Duration duration = const Duration(milliseconds: 10), | 57 | Duration duration = const Duration(milliseconds: 10), |
| 60 | ]) async { | 58 | ]) async { |
| 61 | final binding = WidgetsFlutterBinding.ensureInitialized(); | 59 | final binding = WidgetsFlutterBinding.ensureInitialized(); |
| 62 | - window ??= WidgetsBinding.instance.platformDispatcher.implicitView; | 60 | + binding.deferFirstFrame(); |
| 63 | 61 | ||
| 64 | - if (window?.physicalGeometry.isEmpty == true) { | ||
| 65 | - return Future.delayed(duration, () async { | ||
| 66 | - binding.deferFirstFrame(); | ||
| 67 | - await ensureScreenSize(window, duration); | ||
| 68 | - return binding.allowFirstFrame(); | ||
| 69 | - }); | ||
| 70 | - } | 62 | + await Future.doWhile(() { |
| 63 | + if (window == null) { | ||
| 64 | + window = binding.platformDispatcher.implicitView; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + if (window == null || window!.physicalSize.isEmpty) { | ||
| 68 | + return Future.delayed(duration, () => true); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + return false; | ||
| 72 | + }); | ||
| 73 | + | ||
| 74 | + binding.allowFirstFrame(); | ||
| 71 | } | 75 | } |
| 72 | 76 | ||
| 73 | Set<Element>? _elementsToRebuild; | 77 | Set<Element>? _elementsToRebuild; |
| @@ -88,44 +92,78 @@ class ScreenUtil { | @@ -88,44 +92,78 @@ class ScreenUtil { | ||
| 88 | } | 92 | } |
| 89 | } | 93 | } |
| 90 | 94 | ||
| 91 | - /// Initializing the library. | ||
| 92 | - static Future<void> init(BuildContext context, | ||
| 93 | - {Size designSize = defaultSize, | ||
| 94 | - bool splitScreenMode = false, | ||
| 95 | - bool minTextAdapt = false, | ||
| 96 | - bool scaleByHeight = false}) async { | ||
| 97 | - final mediaQueryContext = | ||
| 98 | - context.getElementForInheritedWidgetOfExactType<MediaQuery>(); | ||
| 99 | - | ||
| 100 | - final initCompleter = Completer<void>(); | ||
| 101 | - | ||
| 102 | - WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((_) { | ||
| 103 | - mediaQueryContext?.visitChildElements((el) => _instance._context = el); | ||
| 104 | - if (_instance._context != null) initCompleter.complete(); | ||
| 105 | - }); | 95 | + static void configure({ |
| 96 | + MediaQueryData? data, | ||
| 97 | + Size? designSize, | ||
| 98 | + bool? splitScreenMode, | ||
| 99 | + bool? minTextAdapt, | ||
| 100 | + FontSizeResolver? fontSizeResolver, | ||
| 101 | + }) { | ||
| 102 | + try { | ||
| 103 | + if (data != null) | ||
| 104 | + _instance._data = data; | ||
| 105 | + else | ||
| 106 | + data = _instance._data; | ||
| 107 | + | ||
| 108 | + if (designSize != null) | ||
| 109 | + _instance._uiSize = designSize; | ||
| 110 | + else | ||
| 111 | + designSize = _instance._uiSize; | ||
| 112 | + } catch (_) { | ||
| 113 | + throw Exception( | ||
| 114 | + 'You must either use ScreenUtil.init or ScreenUtilInit first'); | ||
| 115 | + } | ||
| 106 | 116 | ||
| 107 | - final deviceData = MediaQuery.maybeOf(context).nonEmptySizeOrNull(); | 117 | + final MediaQueryData? deviceData = data.nonEmptySizeOrNull(); |
| 118 | + final Size deviceSize = deviceData?.size ?? designSize; | ||
| 108 | 119 | ||
| 109 | - final deviceSize = deviceData?.size ?? designSize; | ||
| 110 | final orientation = deviceData?.orientation ?? | 120 | final orientation = deviceData?.orientation ?? |
| 111 | (deviceSize.width > deviceSize.height | 121 | (deviceSize.width > deviceSize.height |
| 112 | ? Orientation.landscape | 122 | ? Orientation.landscape |
| 113 | : Orientation.portrait); | 123 | : Orientation.portrait); |
| 114 | 124 | ||
| 115 | _instance | 125 | _instance |
| 116 | - .._context = scaleByHeight ? null : context | ||
| 117 | - .._uiSize = designSize | ||
| 118 | - .._splitScreenMode = splitScreenMode | ||
| 119 | - .._minTextAdapt = minTextAdapt | ||
| 120 | - .._orientation = orientation | ||
| 121 | - .._screenWidth = scaleByHeight | ||
| 122 | - ? (deviceSize.height * designSize.width) / designSize.height | ||
| 123 | - : deviceSize.width | ||
| 124 | - .._screenHeight = deviceSize.height; | 126 | + ..fontSizeResolver = fontSizeResolver ?? _instance.fontSizeResolver |
| 127 | + .._minTextAdapt = minTextAdapt ?? _instance._minTextAdapt | ||
| 128 | + .._splitScreenMode = splitScreenMode ?? _instance._splitScreenMode | ||
| 129 | + .._orientation = orientation; | ||
| 125 | 130 | ||
| 126 | _instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild()); | 131 | _instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild()); |
| 132 | + } | ||
| 133 | + | ||
| 134 | + /// Initializing the library. | ||
| 135 | + static void init( | ||
| 136 | + BuildContext context, { | ||
| 137 | + Size designSize = defaultSize, | ||
| 138 | + bool splitScreenMode = false, | ||
| 139 | + bool minTextAdapt = false, | ||
| 140 | + FontSizeResolver? fontSizeResolver, | ||
| 141 | + }) { | ||
| 142 | + return configure( | ||
| 143 | + data: MediaQuery.maybeOf(context), | ||
| 144 | + designSize: designSize, | ||
| 145 | + splitScreenMode: splitScreenMode, | ||
| 146 | + minTextAdapt: minTextAdapt, | ||
| 147 | + fontSizeResolver: fontSizeResolver, | ||
| 148 | + ); | ||
| 149 | + } | ||
| 127 | 150 | ||
| 128 | - return initCompleter.future; | 151 | + static Future<void> ensureScreenSizeAndInit( |
| 152 | + BuildContext context, { | ||
| 153 | + Size designSize = defaultSize, | ||
| 154 | + bool splitScreenMode = false, | ||
| 155 | + bool minTextAdapt = false, | ||
| 156 | + FontSizeResolver? fontSizeResolver, | ||
| 157 | + }) { | ||
| 158 | + return ScreenUtil.ensureScreenSize().then((_) { | ||
| 159 | + return configure( | ||
| 160 | + data: MediaQuery.maybeOf(context), | ||
| 161 | + designSize: designSize, | ||
| 162 | + minTextAdapt: minTextAdapt, | ||
| 163 | + splitScreenMode: splitScreenMode, | ||
| 164 | + fontSizeResolver: fontSizeResolver, | ||
| 165 | + ); | ||
| 166 | + }); | ||
| 129 | } | 167 | } |
| 130 | 168 | ||
| 131 | ///获取屏幕方向 | 169 | ///获取屏幕方向 |
| @@ -134,39 +172,33 @@ class ScreenUtil { | @@ -134,39 +172,33 @@ class ScreenUtil { | ||
| 134 | 172 | ||
| 135 | /// 每个逻辑像素的字体像素数,字体的缩放比例 | 173 | /// 每个逻辑像素的字体像素数,字体的缩放比例 |
| 136 | /// The number of font pixels for each logical pixel. | 174 | /// The number of font pixels for each logical pixel. |
| 137 | - double get textScaleFactor => | ||
| 138 | - _context != null ? MediaQuery.of(_context!).textScaleFactor : 1; | 175 | + double get textScaleFactor => _data.textScaleFactor; |
| 139 | 176 | ||
| 140 | /// 设备的像素密度 | 177 | /// 设备的像素密度 |
| 141 | /// The size of the media in logical pixels (e.g, the size of the screen). | 178 | /// The size of the media in logical pixels (e.g, the size of the screen). |
| 142 | - double? get pixelRatio => | ||
| 143 | - _context != null ? MediaQuery.of(_context!).devicePixelRatio : 1; | 179 | + double? get pixelRatio => _data.devicePixelRatio; |
| 144 | 180 | ||
| 145 | /// 当前设备宽度 dp | 181 | /// 当前设备宽度 dp |
| 146 | /// The horizontal extent of this size. | 182 | /// The horizontal extent of this size. |
| 147 | - double get screenWidth => | ||
| 148 | - _context != null ? MediaQuery.of(_context!).size.width : _screenWidth; | 183 | + double get screenWidth => _data.size.width; |
| 149 | 184 | ||
| 150 | ///当前设备高度 dp | 185 | ///当前设备高度 dp |
| 151 | ///The vertical extent of this size. dp | 186 | ///The vertical extent of this size. dp |
| 152 | - double get screenHeight => | ||
| 153 | - _context != null ? MediaQuery.of(_context!).size.height : _screenHeight; | 187 | + double get screenHeight => _data.size.height; |
| 154 | 188 | ||
| 155 | /// 状态栏高度 dp 刘海屏会更高 | 189 | /// 状态栏高度 dp 刘海屏会更高 |
| 156 | /// The offset from the top, in dp | 190 | /// The offset from the top, in dp |
| 157 | - double get statusBarHeight => | ||
| 158 | - _context == null ? 0 : MediaQuery.of(_context!).padding.top; | 191 | + double get statusBarHeight => _data.padding.top; |
| 159 | 192 | ||
| 160 | /// 底部安全区距离 dp | 193 | /// 底部安全区距离 dp |
| 161 | /// The offset from the bottom, in dp | 194 | /// The offset from the bottom, in dp |
| 162 | - double get bottomBarHeight => | ||
| 163 | - _context == null ? 0 : MediaQuery.of(_context!).padding.bottom; | 195 | + double get bottomBarHeight => _data.padding.bottom; |
| 164 | 196 | ||
| 165 | /// 实际尺寸与UI设计的比例 | 197 | /// 实际尺寸与UI设计的比例 |
| 166 | /// The ratio of actual width to UI design | 198 | /// The ratio of actual width to UI design |
| 167 | double get scaleWidth => screenWidth / _uiSize.width; | 199 | double get scaleWidth => screenWidth / _uiSize.width; |
| 168 | 200 | ||
| 169 | - /// /// The ratio of actual height to UI design | 201 | + /// The ratio of actual height to UI design |
| 170 | double get scaleHeight => | 202 | double get scaleHeight => |
| 171 | (_splitScreenMode ? max(screenHeight, 700) : screenHeight) / | 203 | (_splitScreenMode ? max(screenHeight, 700) : screenHeight) / |
| 172 | _uiSize.height; | 204 | _uiSize.height; |
| @@ -195,24 +227,44 @@ class ScreenUtil { | @@ -195,24 +227,44 @@ class ScreenUtil { | ||
| 195 | ///Adapt according to the smaller of width or height | 227 | ///Adapt according to the smaller of width or height |
| 196 | double radius(num r) => r * min(scaleWidth, scaleHeight); | 228 | double radius(num r) => r * min(scaleWidth, scaleHeight); |
| 197 | 229 | ||
| 230 | + /// Adapt according to the both width and height | ||
| 231 | + double diagonal(num d) => d * scaleHeight * scaleWidth; | ||
| 232 | + | ||
| 233 | + /// Adapt according to the maximum value of scale width and scale height | ||
| 234 | + double diameter(num d) => d * max(scaleWidth, scaleHeight); | ||
| 235 | + | ||
| 198 | ///字体大小适配方法 | 236 | ///字体大小适配方法 |
| 199 | ///- [fontSize] UI设计上字体的大小,单位dp. | 237 | ///- [fontSize] UI设计上字体的大小,单位dp. |
| 200 | ///Font size adaptation method | 238 | ///Font size adaptation method |
| 201 | ///- [fontSize] The size of the font on the UI design, in dp. | 239 | ///- [fontSize] The size of the font on the UI design, in dp. |
| 202 | - double setSp(num fontSize) => fontSize * scaleText; | 240 | + double setSp(num fontSize) => |
| 241 | + fontSizeResolver?.call(fontSize, _instance) ?? fontSize * scaleText; | ||
| 203 | 242 | ||
| 204 | - Widget setVerticalSpacing(num height) => SizedBox(height: setHeight(height)); | 243 | + SizedBox setVerticalSpacing(num height) => |
| 244 | + SizedBox(height: setHeight(height)); | ||
| 205 | 245 | ||
| 206 | - Widget setVerticalSpacingFromWidth(num height) => | 246 | + SizedBox setVerticalSpacingFromWidth(num height) => |
| 207 | SizedBox(height: setWidth(height)); | 247 | SizedBox(height: setWidth(height)); |
| 208 | 248 | ||
| 209 | - Widget setHorizontalSpacing(num width) => SizedBox(width: setWidth(width)); | 249 | + SizedBox setHorizontalSpacing(num width) => SizedBox(width: setWidth(width)); |
| 210 | 250 | ||
| 211 | - Widget setHorizontalSpacingRadius(num width) => | 251 | + SizedBox setHorizontalSpacingRadius(num width) => |
| 212 | SizedBox(width: radius(width)); | 252 | SizedBox(width: radius(width)); |
| 213 | 253 | ||
| 214 | - Widget setVerticalSpacingRadius(num height) => | 254 | + SizedBox setVerticalSpacingRadius(num height) => |
| 215 | SizedBox(height: radius(height)); | 255 | SizedBox(height: radius(height)); |
| 256 | + | ||
| 257 | + SizedBox setHorizontalSpacingDiameter(num width) => | ||
| 258 | + SizedBox(width: diameter(width)); | ||
| 259 | + | ||
| 260 | + SizedBox setVerticalSpacingDiameter(num height) => | ||
| 261 | + SizedBox(height: diameter(height)); | ||
| 262 | + | ||
| 263 | + SizedBox setHorizontalSpacingDiagonal(num width) => | ||
| 264 | + SizedBox(width: diagonal(width)); | ||
| 265 | + | ||
| 266 | + SizedBox setVerticalSpacingDiagonal(num height) => | ||
| 267 | + SizedBox(height: diagonal(height)); | ||
| 216 | } | 268 | } |
| 217 | 269 | ||
| 218 | extension on MediaQueryData? { | 270 | extension on MediaQueryData? { |
| 1 | +import 'dart:async'; | ||
| 2 | +import 'dart:collection'; | ||
| 3 | + | ||
| 1 | import 'package:flutter/widgets.dart'; | 4 | import 'package:flutter/widgets.dart'; |
| 5 | +import './_flutter_widgets.dart'; | ||
| 2 | 6 | ||
| 7 | +import 'screenutil_mixin.dart'; | ||
| 3 | import 'screen_util.dart'; | 8 | import 'screen_util.dart'; |
| 4 | 9 | ||
| 5 | typedef RebuildFactor = bool Function(MediaQueryData old, MediaQueryData data); | 10 | typedef RebuildFactor = bool Function(MediaQueryData old, MediaQueryData data); |
| @@ -9,9 +14,7 @@ typedef ScreenUtilInitBuilder = Widget Function( | @@ -9,9 +14,7 @@ typedef ScreenUtilInitBuilder = Widget Function( | ||
| 9 | Widget? child, | 14 | Widget? child, |
| 10 | ); | 15 | ); |
| 11 | 16 | ||
| 12 | -class RebuildFactors { | ||
| 13 | - const RebuildFactors._(); | ||
| 14 | - | 17 | +abstract class RebuildFactors { |
| 15 | static bool size(MediaQueryData old, MediaQueryData data) { | 18 | static bool size(MediaQueryData old, MediaQueryData data) { |
| 16 | return old.size != data.size; | 19 | return old.size != data.size; |
| 17 | } | 20 | } |
| @@ -24,35 +27,69 @@ class RebuildFactors { | @@ -24,35 +27,69 @@ class RebuildFactors { | ||
| 24 | return old.viewInsets != data.viewInsets; | 27 | return old.viewInsets != data.viewInsets; |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | - static bool all(MediaQueryData old, MediaQueryData data) { | 30 | + static bool change(MediaQueryData old, MediaQueryData data) { |
| 28 | return old != data; | 31 | return old != data; |
| 29 | } | 32 | } |
| 33 | + | ||
| 34 | + static bool always(MediaQueryData _, MediaQueryData __) { | ||
| 35 | + return true; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + static bool none(MediaQueryData _, MediaQueryData __) { | ||
| 39 | + return false; | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +abstract class FontSizeResolvers { | ||
| 44 | + static double width(num fontSize, ScreenUtil instance) { | ||
| 45 | + return instance.setWidth(fontSize); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + static double height(num fontSize, ScreenUtil instance) { | ||
| 49 | + return instance.setHeight(fontSize); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + static double raduis(num fontSize, ScreenUtil instance) { | ||
| 53 | + return instance.radius(fontSize); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + static double diameter(num fontSize, ScreenUtil instance) { | ||
| 57 | + return instance.diameter(fontSize); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + static double diagonal(num fontSize, ScreenUtil instance) { | ||
| 61 | + return instance.diagonal(fontSize); | ||
| 62 | + } | ||
| 30 | } | 63 | } |
| 31 | 64 | ||
| 32 | class ScreenUtilInit extends StatefulWidget { | 65 | class ScreenUtilInit extends StatefulWidget { |
| 33 | /// A helper widget that initializes [ScreenUtil] | 66 | /// A helper widget that initializes [ScreenUtil] |
| 34 | - const ScreenUtilInit( | ||
| 35 | - {Key? key, | ||
| 36 | - required this.builder, | ||
| 37 | - this.child, | ||
| 38 | - this.rebuildFactor = RebuildFactors.size, | ||
| 39 | - this.designSize = ScreenUtil.defaultSize, | ||
| 40 | - this.splitScreenMode = false, | ||
| 41 | - this.minTextAdapt = false, | ||
| 42 | - this.useInheritedMediaQuery = false, | ||
| 43 | - this.scaleByHeight = false}) | ||
| 44 | - : super(key: key); | ||
| 45 | - | ||
| 46 | - final ScreenUtilInitBuilder builder; | 67 | + const ScreenUtilInit({ |
| 68 | + Key? key, | ||
| 69 | + this.builder, | ||
| 70 | + this.child, | ||
| 71 | + this.rebuildFactor = RebuildFactors.size, | ||
| 72 | + this.designSize = ScreenUtil.defaultSize, | ||
| 73 | + this.splitScreenMode = false, | ||
| 74 | + this.minTextAdapt = false, | ||
| 75 | + this.useInheritedMediaQuery = false, | ||
| 76 | + this.ensureScreenSize, | ||
| 77 | + this.responsiveWidgets, | ||
| 78 | + this.fontSizeResolver = FontSizeResolvers.width, | ||
| 79 | + }) : super(key: key); | ||
| 80 | + | ||
| 81 | + final ScreenUtilInitBuilder? builder; | ||
| 47 | final Widget? child; | 82 | final Widget? child; |
| 48 | final bool splitScreenMode; | 83 | final bool splitScreenMode; |
| 49 | final bool minTextAdapt; | 84 | final bool minTextAdapt; |
| 50 | final bool useInheritedMediaQuery; | 85 | final bool useInheritedMediaQuery; |
| 51 | - final bool scaleByHeight; | 86 | + final bool? ensureScreenSize; |
| 52 | final RebuildFactor rebuildFactor; | 87 | final RebuildFactor rebuildFactor; |
| 88 | + final FontSizeResolver fontSizeResolver; | ||
| 53 | 89 | ||
| 54 | /// The [Size] of the device in the design draft, in dp | 90 | /// The [Size] of the device in the design draft, in dp |
| 55 | final Size designSize; | 91 | final Size designSize; |
| 92 | + final Iterable<String>? responsiveWidgets; | ||
| 56 | 93 | ||
| 57 | @override | 94 | @override |
| 58 | State<ScreenUtilInit> createState() => _ScreenUtilInitState(); | 95 | State<ScreenUtilInit> createState() => _ScreenUtilInitState(); |
| @@ -60,127 +97,103 @@ class ScreenUtilInit extends StatefulWidget { | @@ -60,127 +97,103 @@ class ScreenUtilInit extends StatefulWidget { | ||
| 60 | 97 | ||
| 61 | class _ScreenUtilInitState extends State<ScreenUtilInit> | 98 | class _ScreenUtilInitState extends State<ScreenUtilInit> |
| 62 | with WidgetsBindingObserver { | 99 | with WidgetsBindingObserver { |
| 100 | + final _canMarkedToBuild = HashSet<String>(); | ||
| 63 | MediaQueryData? _mediaQueryData; | 101 | MediaQueryData? _mediaQueryData; |
| 102 | + final _binding = WidgetsBinding.instance; | ||
| 103 | + final _screenSizeCompleter = Completer<void>(); | ||
| 64 | 104 | ||
| 65 | - bool wrappedInMediaQuery = false; | 105 | + @override |
| 106 | + void initState() { | ||
| 107 | + if (widget.responsiveWidgets != null) { | ||
| 108 | + _canMarkedToBuild.addAll(widget.responsiveWidgets!); | ||
| 109 | + } | ||
| 110 | + _validateSize().then(_screenSizeCompleter.complete); | ||
| 66 | 111 | ||
| 67 | - WidgetsBinding get binding => WidgetsFlutterBinding.ensureInitialized(); | 112 | + super.initState(); |
| 113 | + _binding.addObserver(this); | ||
| 114 | + } | ||
| 68 | 115 | ||
| 69 | - MediaQueryData get mediaQueryData => _mediaQueryData!; | 116 | + @override |
| 117 | + void didChangeMetrics() { | ||
| 118 | + super.didChangeMetrics(); | ||
| 119 | + _revalidate(); | ||
| 120 | + } | ||
| 70 | 121 | ||
| 71 | - MediaQueryData get newData { | ||
| 72 | - final data = MediaQuery.maybeOf(context); | 122 | + @override |
| 123 | + void didChangeDependencies() { | ||
| 124 | + super.didChangeDependencies(); | ||
| 125 | + _revalidate(); | ||
| 126 | + } | ||
| 73 | 127 | ||
| 74 | - if (data != null) { | ||
| 75 | - if (widget.useInheritedMediaQuery) { | ||
| 76 | - wrappedInMediaQuery = true; | ||
| 77 | - } | ||
| 78 | - return data; | ||
| 79 | - } | 128 | + MediaQueryData? _newData() { |
| 129 | + MediaQueryData? mq = MediaQuery.maybeOf(context); | ||
| 130 | + if (mq == null) mq = MediaQueryData.fromView(View.of(context)); | ||
| 80 | 131 | ||
| 81 | - return MediaQueryData.fromView(View.of(context)); | 132 | + return mq; |
| 82 | } | 133 | } |
| 83 | 134 | ||
| 84 | - _updateTree(Element el) { | ||
| 85 | - el.markNeedsBuild(); | ||
| 86 | - el.visitChildren(_updateTree); | 135 | + Future<void> _validateSize() async { |
| 136 | + if (widget.ensureScreenSize ?? false) return ScreenUtil.ensureScreenSize(); | ||
| 87 | } | 137 | } |
| 88 | 138 | ||
| 89 | - @override | ||
| 90 | - void initState() { | ||
| 91 | - super.initState(); | ||
| 92 | - binding.addObserver(this); | 139 | + void _markNeedsBuildIfAllowed(Element el) { |
| 140 | + final widgetName = el.widget.runtimeType.toString(); | ||
| 141 | + final allowed = widget is SU || | ||
| 142 | + _canMarkedToBuild.contains(widgetName) || | ||
| 143 | + !(widgetName.startsWith('_') || flutterWidgets.contains(widgetName)); | ||
| 144 | + | ||
| 145 | + if (allowed) el.markNeedsBuild(); | ||
| 93 | } | 146 | } |
| 94 | 147 | ||
| 95 | - @override | ||
| 96 | - void didChangeMetrics() { | ||
| 97 | - final old = _mediaQueryData!; | ||
| 98 | - final data = newData; | 148 | + void _updateTree(Element el) { |
| 149 | + _markNeedsBuildIfAllowed(el); | ||
| 150 | + el.visitChildren(_updateTree); | ||
| 151 | + } | ||
| 99 | 152 | ||
| 100 | - if (widget.scaleByHeight || widget.rebuildFactor(old, data)) { | ||
| 101 | - _mediaQueryData = data; | ||
| 102 | - _updateTree(context as Element); | 153 | + void _revalidate([void Function()? callback]) { |
| 154 | + final oldData = _mediaQueryData; | ||
| 155 | + final newData = _newData(); | ||
| 156 | + | ||
| 157 | + if (newData == null) return; | ||
| 158 | + | ||
| 159 | + if (oldData == null || widget.rebuildFactor(oldData, newData)) { | ||
| 160 | + setState(() { | ||
| 161 | + _mediaQueryData = newData; | ||
| 162 | + _updateTree(context as Element); | ||
| 163 | + callback?.call(); | ||
| 164 | + }); | ||
| 103 | } | 165 | } |
| 104 | } | 166 | } |
| 105 | 167 | ||
| 106 | @override | 168 | @override |
| 107 | - void didChangeDependencies() { | ||
| 108 | - super.didChangeDependencies(); | ||
| 109 | - if (_mediaQueryData == null) _mediaQueryData = newData; | ||
| 110 | - didChangeMetrics(); | 169 | + Widget build(BuildContext context) { |
| 170 | + final mq = _mediaQueryData; | ||
| 171 | + | ||
| 172 | + if (mq == null) return const SizedBox.shrink(); | ||
| 173 | + | ||
| 174 | + return FutureBuilder<void>( | ||
| 175 | + future: _screenSizeCompleter.future, | ||
| 176 | + builder: (c, snapshot) { | ||
| 177 | + ScreenUtil.configure( | ||
| 178 | + data: mq, | ||
| 179 | + designSize: widget.designSize, | ||
| 180 | + splitScreenMode: widget.splitScreenMode, | ||
| 181 | + minTextAdapt: widget.minTextAdapt, | ||
| 182 | + fontSizeResolver: widget.fontSizeResolver, | ||
| 183 | + ); | ||
| 184 | + | ||
| 185 | + if (snapshot.connectionState == ConnectionState.done) { | ||
| 186 | + return widget.builder?.call(context, widget.child) ?? widget.child!; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + return const SizedBox.shrink(); | ||
| 190 | + }, | ||
| 191 | + ); | ||
| 111 | } | 192 | } |
| 112 | 193 | ||
| 113 | @override | 194 | @override |
| 114 | void dispose() { | 195 | void dispose() { |
| 115 | - binding.removeObserver(this); | 196 | + _binding.removeObserver(this); |
| 116 | super.dispose(); | 197 | super.dispose(); |
| 117 | } | 198 | } |
| 118 | - | ||
| 119 | - @override | ||
| 120 | - Widget build(BuildContext _context) { | ||
| 121 | - if (mediaQueryData.size == Size.zero) return const SizedBox.shrink(); | ||
| 122 | - if (!wrappedInMediaQuery) { | ||
| 123 | - return MediaQuery( | ||
| 124 | - data: mediaQueryData, | ||
| 125 | - child: Builder( | ||
| 126 | - builder: (__context) { | ||
| 127 | - ScreenUtil.init( | ||
| 128 | - __context, | ||
| 129 | - designSize: widget.designSize, | ||
| 130 | - splitScreenMode: widget.splitScreenMode, | ||
| 131 | - minTextAdapt: widget.minTextAdapt, | ||
| 132 | - scaleByHeight: widget.scaleByHeight, | ||
| 133 | - ); | ||
| 134 | - final deviceData = MediaQuery.maybeOf(__context); | ||
| 135 | - final deviceSize = deviceData?.size ?? widget.designSize; | ||
| 136 | - return MediaQuery( | ||
| 137 | - data: MediaQueryData.fromView(View.of(__context)), | ||
| 138 | - child: Container( | ||
| 139 | - width: deviceSize.width, | ||
| 140 | - height: deviceSize.height, | ||
| 141 | - child: FittedBox( | ||
| 142 | - fit: BoxFit.none, | ||
| 143 | - alignment: Alignment.center, | ||
| 144 | - child: Container( | ||
| 145 | - width: widget.scaleByHeight | ||
| 146 | - ? (deviceSize.height * widget.designSize.width) / | ||
| 147 | - widget.designSize.height | ||
| 148 | - : deviceSize.width, | ||
| 149 | - height: deviceSize.height, | ||
| 150 | - child: widget.builder(__context, widget.child), | ||
| 151 | - ), | ||
| 152 | - ), | ||
| 153 | - ), | ||
| 154 | - ); | ||
| 155 | - }, | ||
| 156 | - ), | ||
| 157 | - ); | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - ScreenUtil.init( | ||
| 161 | - _context, | ||
| 162 | - designSize: widget.designSize, | ||
| 163 | - splitScreenMode: widget.splitScreenMode, | ||
| 164 | - minTextAdapt: widget.minTextAdapt, | ||
| 165 | - scaleByHeight: widget.scaleByHeight, | ||
| 166 | - ); | ||
| 167 | - final deviceData = MediaQuery.maybeOf(_context); | ||
| 168 | - final deviceSize = deviceData?.size ?? widget.designSize; | ||
| 169 | - return Container( | ||
| 170 | - width: deviceSize.width, | ||
| 171 | - height: deviceSize.height, | ||
| 172 | - child: FittedBox( | ||
| 173 | - fit: BoxFit.none, | ||
| 174 | - alignment: Alignment.center, | ||
| 175 | - child: Container( | ||
| 176 | - width: widget.scaleByHeight | ||
| 177 | - ? (deviceSize.height * widget.designSize.width) / | ||
| 178 | - widget.designSize.height | ||
| 179 | - : deviceSize.width, | ||
| 180 | - height: deviceSize.height, | ||
| 181 | - child: widget.builder(_context, widget.child), | ||
| 182 | - ), | ||
| 183 | - ), | ||
| 184 | - ); | ||
| 185 | - } | ||
| 186 | } | 199 | } |
lib/src/screenutil_mixin.dart
0 → 100644
| @@ -14,6 +14,12 @@ extension SizeExtension on num { | @@ -14,6 +14,12 @@ extension SizeExtension on num { | ||
| 14 | ///[ScreenUtil.radius] | 14 | ///[ScreenUtil.radius] |
| 15 | double get r => ScreenUtil().radius(this); | 15 | double get r => ScreenUtil().radius(this); |
| 16 | 16 | ||
| 17 | + ///[ScreenUtil.diagonal] | ||
| 18 | + double get dg => ScreenUtil().diagonal(this); | ||
| 19 | + | ||
| 20 | + ///[ScreenUtil.diameter] | ||
| 21 | + double get dm => ScreenUtil().diameter(this); | ||
| 22 | + | ||
| 17 | ///[ScreenUtil.setSp] | 23 | ///[ScreenUtil.setSp] |
| 18 | double get sp => ScreenUtil().setSp(this); | 24 | double get sp => ScreenUtil().setSp(this); |
| 19 | 25 | ||
| @@ -36,22 +42,38 @@ extension SizeExtension on num { | @@ -36,22 +42,38 @@ extension SizeExtension on num { | ||
| 36 | double get sh => ScreenUtil().screenHeight * this; | 42 | double get sh => ScreenUtil().screenHeight * this; |
| 37 | 43 | ||
| 38 | ///[ScreenUtil.setHeight] | 44 | ///[ScreenUtil.setHeight] |
| 39 | - Widget get verticalSpace => ScreenUtil().setVerticalSpacing(this); | 45 | + SizedBox get verticalSpace => ScreenUtil().setVerticalSpacing(this); |
| 40 | 46 | ||
| 41 | ///[ScreenUtil.setVerticalSpacingFromWidth] | 47 | ///[ScreenUtil.setVerticalSpacingFromWidth] |
| 42 | - Widget get verticalSpaceFromWidth => | 48 | + SizedBox get verticalSpaceFromWidth => |
| 43 | ScreenUtil().setVerticalSpacingFromWidth(this); | 49 | ScreenUtil().setVerticalSpacingFromWidth(this); |
| 44 | 50 | ||
| 45 | ///[ScreenUtil.setWidth] | 51 | ///[ScreenUtil.setWidth] |
| 46 | - Widget get horizontalSpace => ScreenUtil().setHorizontalSpacing(this); | 52 | + SizedBox get horizontalSpace => ScreenUtil().setHorizontalSpacing(this); |
| 47 | 53 | ||
| 48 | ///[ScreenUtil.radius] | 54 | ///[ScreenUtil.radius] |
| 49 | - Widget get horizontalSpaceRadius => | 55 | + SizedBox get horizontalSpaceRadius => |
| 50 | ScreenUtil().setHorizontalSpacingRadius(this); | 56 | ScreenUtil().setHorizontalSpacingRadius(this); |
| 51 | 57 | ||
| 52 | ///[ScreenUtil.radius] | 58 | ///[ScreenUtil.radius] |
| 53 | - Widget get verticalSpacingRadius => | 59 | + SizedBox get verticalSpacingRadius => |
| 54 | ScreenUtil().setVerticalSpacingRadius(this); | 60 | ScreenUtil().setVerticalSpacingRadius(this); |
| 61 | + | ||
| 62 | + ///[ScreenUtil.diameter] | ||
| 63 | + SizedBox get horizontalSpaceDiameter => | ||
| 64 | + ScreenUtil().setHorizontalSpacingDiameter(this); | ||
| 65 | + | ||
| 66 | + ///[ScreenUtil.diameter] | ||
| 67 | + SizedBox get verticalSpacingDiameter => | ||
| 68 | + ScreenUtil().setVerticalSpacingDiameter(this); | ||
| 69 | + | ||
| 70 | + ///[ScreenUtil.diagonal] | ||
| 71 | + SizedBox get horizontalSpaceDiagonal => | ||
| 72 | + ScreenUtil().setHorizontalSpacingDiagonal(this); | ||
| 73 | + | ||
| 74 | + ///[ScreenUtil.diagonal] | ||
| 75 | + SizedBox get verticalSpacingDiagonal => | ||
| 76 | + ScreenUtil().setVerticalSpacingDiagonal(this); | ||
| 55 | } | 77 | } |
| 56 | 78 | ||
| 57 | extension EdgeInsetsExtension on EdgeInsets { | 79 | extension EdgeInsetsExtension on EdgeInsets { |
| @@ -63,6 +85,20 @@ extension EdgeInsetsExtension on EdgeInsets { | @@ -63,6 +85,20 @@ extension EdgeInsetsExtension on EdgeInsets { | ||
| 63 | left: left.r, | 85 | left: left.r, |
| 64 | ); | 86 | ); |
| 65 | 87 | ||
| 88 | + EdgeInsets get dm => copyWith( | ||
| 89 | + top: top.dm, | ||
| 90 | + bottom: bottom.dm, | ||
| 91 | + right: right.dm, | ||
| 92 | + left: left.dm, | ||
| 93 | + ); | ||
| 94 | + | ||
| 95 | + EdgeInsets get dg => copyWith( | ||
| 96 | + top: top.dg, | ||
| 97 | + bottom: bottom.dg, | ||
| 98 | + right: right.dg, | ||
| 99 | + left: left.dg, | ||
| 100 | + ); | ||
| 101 | + | ||
| 66 | EdgeInsets get w => copyWith( | 102 | EdgeInsets get w => copyWith( |
| 67 | top: top.w, | 103 | top: top.w, |
| 68 | bottom: bottom.w, | 104 | bottom: bottom.w, |
| @@ -106,6 +142,10 @@ extension RaduisExtension on Radius { | @@ -106,6 +142,10 @@ extension RaduisExtension on Radius { | ||
| 106 | /// Creates adapt Radius using r [SizeExtension]. | 142 | /// Creates adapt Radius using r [SizeExtension]. |
| 107 | Radius get r => Radius.elliptical(x.r, y.r); | 143 | Radius get r => Radius.elliptical(x.r, y.r); |
| 108 | 144 | ||
| 145 | + Radius get dm => Radius.elliptical(x.dm, y.dm); | ||
| 146 | + | ||
| 147 | + Radius get dg => Radius.elliptical(x.dg, y.dg); | ||
| 148 | + | ||
| 109 | Radius get w => Radius.elliptical(x.w, y.w); | 149 | Radius get w => Radius.elliptical(x.w, y.w); |
| 110 | 150 | ||
| 111 | Radius get h => Radius.elliptical(x.h, y.h); | 151 | Radius get h => Radius.elliptical(x.h, y.h); |
| 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.8.4 | 3 | +version: 5.9.0-beta |
| 4 | homepage: https://github.com/OpenFlutter/flutter_screenutil | 4 | homepage: https://github.com/OpenFlutter/flutter_screenutil |
| 5 | 5 | ||
| 6 | environment: | 6 | environment: |
| 7 | - sdk: ">=2.12.0 <4.0.0" | 7 | + sdk: ">=2.17.0 <4.0.0" |
| 8 | flutter: ">=3.10.0" | 8 | flutter: ">=3.10.0" |
| 9 | 9 | ||
| 10 | dependencies: | 10 | dependencies: |
test/flutter_screenutil_test.dart
0 → 100644
| 1 | +import 'package:flutter/material.dart'; | ||
| 2 | +import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
| 3 | +import 'package:flutter_test/flutter_test.dart'; | ||
| 4 | + | ||
| 5 | +import 'home.test.dart'; | ||
| 6 | + | ||
| 7 | +void main() { | ||
| 8 | + const smallerDeviceSize = Size(300, 600); | ||
| 9 | + const smallerDeviceData = MediaQueryData(size: smallerDeviceSize); | ||
| 10 | + | ||
| 11 | + const biggerDeviceSize = Size(500, 900); | ||
| 12 | + const biggerDeviceData = MediaQueryData(size: biggerDeviceSize); | ||
| 13 | + | ||
| 14 | + const uiSize = Size(470, 740); | ||
| 15 | + | ||
| 16 | + group('[Test calculations]', () { | ||
| 17 | + test('Test smaller size', () { | ||
| 18 | + ScreenUtil.configure( | ||
| 19 | + data: smallerDeviceData, | ||
| 20 | + designSize: uiSize, | ||
| 21 | + minTextAdapt: true, | ||
| 22 | + splitScreenMode: false, | ||
| 23 | + ); | ||
| 24 | + | ||
| 25 | + expect(1.w, smallerDeviceSize.width / uiSize.width); | ||
| 26 | + expect(1.w < 1, true); | ||
| 27 | + expect(1.h, smallerDeviceSize.height / uiSize.height); | ||
| 28 | + expect(1.h < 1, true); | ||
| 29 | + }); | ||
| 30 | + | ||
| 31 | + test('Test bigger size', () { | ||
| 32 | + ScreenUtil.configure( | ||
| 33 | + data: biggerDeviceData, | ||
| 34 | + designSize: uiSize, | ||
| 35 | + minTextAdapt: true, | ||
| 36 | + splitScreenMode: false, | ||
| 37 | + ); | ||
| 38 | + | ||
| 39 | + expect(1.w, biggerDeviceSize.width / uiSize.width); | ||
| 40 | + expect(1.w > 1, true); | ||
| 41 | + expect(1.h, biggerDeviceSize.height / uiSize.height); | ||
| 42 | + expect(1.h > 1, true); | ||
| 43 | + }); | ||
| 44 | + }); | ||
| 45 | + | ||
| 46 | + group('[Test overflow]', () { | ||
| 47 | + testWidgets('Test overflow width', (tester) async { | ||
| 48 | + await tester.pumpWidget(ScreenUtilInit( | ||
| 49 | + designSize: uiSize, | ||
| 50 | + child: MaterialApp(home: WidgetTest(width: () => uiSize.width.w)), | ||
| 51 | + )); | ||
| 52 | + | ||
| 53 | + // Wait until all widget rendered | ||
| 54 | + await tester.pumpAndSettle(); | ||
| 55 | + | ||
| 56 | + // a Text widget must be present | ||
| 57 | + expect(find.text('Test'), findsOneWidget); | ||
| 58 | + }); | ||
| 59 | + | ||
| 60 | + testWidgets('Test overflow height', (tester) async { | ||
| 61 | + await tester.pumpWidget(ScreenUtilInit( | ||
| 62 | + designSize: uiSize, | ||
| 63 | + child: MaterialApp(home: WidgetTest(height: () => uiSize.height.h)), | ||
| 64 | + )); | ||
| 65 | + | ||
| 66 | + // Wait until all widget rendered | ||
| 67 | + await tester.pumpAndSettle(); | ||
| 68 | + | ||
| 69 | + // a Text widget must be present | ||
| 70 | + expect(find.text('Test'), findsOneWidget); | ||
| 71 | + }); | ||
| 72 | + }); | ||
| 73 | + | ||
| 74 | + testWidgets('[Rebuilding]', (tester) async { | ||
| 75 | + final textFieldKey = UniqueKey(); | ||
| 76 | + final buildCountNotifier = ValueNotifier(0); | ||
| 77 | + final focusNode = FocusNode(); | ||
| 78 | + | ||
| 79 | + Finder textField() => find.byKey(textFieldKey); | ||
| 80 | + | ||
| 81 | + await tester.pumpWidget(ScreenUtilInit( | ||
| 82 | + designSize: uiSize, | ||
| 83 | + rebuildFactor: RebuildFactors.always, | ||
| 84 | + child: MaterialApp( | ||
| 85 | + home: Scaffold( | ||
| 86 | + body: Builder( | ||
| 87 | + builder: (context) { | ||
| 88 | + buildCountNotifier.value += 1; | ||
| 89 | + | ||
| 90 | + assert(uiSize.width.w == MediaQuery.of(context).size.width); | ||
| 91 | + | ||
| 92 | + return SizedBox( | ||
| 93 | + width: 1.sw, | ||
| 94 | + child: Column( | ||
| 95 | + children: [ | ||
| 96 | + ValueListenableBuilder<int>( | ||
| 97 | + valueListenable: buildCountNotifier, | ||
| 98 | + builder: (_, count, __) => Text('Built count: $count'), | ||
| 99 | + ), | ||
| 100 | + TextField( | ||
| 101 | + key: textFieldKey, | ||
| 102 | + focusNode: focusNode, | ||
| 103 | + ), | ||
| 104 | + ], | ||
| 105 | + ), | ||
| 106 | + ); | ||
| 107 | + }, | ||
| 108 | + ), | ||
| 109 | + ), | ||
| 110 | + ), | ||
| 111 | + )); | ||
| 112 | + | ||
| 113 | + await tester.pumpAndSettle(); | ||
| 114 | + expect(buildCountNotifier.value, 1); | ||
| 115 | + | ||
| 116 | + expect(textField(), findsOneWidget); | ||
| 117 | + expect(focusNode.hasFocus, false); | ||
| 118 | + | ||
| 119 | + await tester.tap(textField()).then((_) => tester.pumpAndSettle()); | ||
| 120 | + expect(textField(), findsOneWidget); | ||
| 121 | + expect(focusNode.hasFocus, true); | ||
| 122 | + expect(buildCountNotifier.value, 1); | ||
| 123 | + | ||
| 124 | + // Simulate keyboard | ||
| 125 | + tester.view.viewInsets = FakeViewPadding(bottom: 20); | ||
| 126 | + | ||
| 127 | + await tester.pumpAndSettle(); | ||
| 128 | + expect(focusNode.hasFocus, true); | ||
| 129 | + expect(buildCountNotifier.value, 1); | ||
| 130 | + }); | ||
| 131 | +} |
test/home.test.dart
0 → 100644
| 1 | +import 'package:flutter/widgets.dart'; | ||
| 2 | + | ||
| 3 | +class WidgetTest extends StatelessWidget { | ||
| 4 | + const WidgetTest({ | ||
| 5 | + super.key, | ||
| 6 | + this.width = _zero, | ||
| 7 | + this.height = _zero, | ||
| 8 | + }); | ||
| 9 | + | ||
| 10 | + final double Function() width; | ||
| 11 | + final double Function() height; | ||
| 12 | + | ||
| 13 | + @override | ||
| 14 | + Widget build(BuildContext context) { | ||
| 15 | + return LayoutBuilder( | ||
| 16 | + builder: (_, c) { | ||
| 17 | + final w = width(), h = height(); | ||
| 18 | + | ||
| 19 | + if (c.biggest >= Size(w, h)) { | ||
| 20 | + return const Text('Test'); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + throw Error(); | ||
| 24 | + }, | ||
| 25 | + ); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + static double _zero() => 0; | ||
| 29 | +} |
-
Please register or login to post a comment