Showing
5 changed files
with
62 additions
and
44 deletions
@@ -9,9 +9,8 @@ class MyApp extends StatelessWidget { | @@ -9,9 +9,8 @@ class MyApp extends StatelessWidget { | ||
9 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
10 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it | 10 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it |
11 | return ScreenUtilInit( | 11 | return ScreenUtilInit( |
12 | - builder: (child) { | 12 | + builder: (_, child) { |
13 | return MaterialApp( | 13 | return MaterialApp( |
14 | - key: const GlobalObjectKey('screen-util'), | ||
15 | debugShowCheckedModeBanner: false, | 14 | debugShowCheckedModeBanner: false, |
16 | title: 'First Method', | 15 | title: 'First Method', |
17 | // You can use the library anywhere in the app even in theme | 16 | // You can use the library anywhere in the app even in theme |
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart'; | @@ -3,7 +3,7 @@ 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 { |
6 | - const HomePageScaffold({Key? key, required this.title}) : super(key: key); | 6 | + const HomePageScaffold({Key? key, this.title = ''}) : super(key: key); |
7 | 7 | ||
8 | void printScreenInformation() { | 8 | void printScreenInformation() { |
9 | print('Device Size:${Size(1.sw, 1.sh)}'); | 9 | print('Device Size:${Size(1.sw, 1.sh)}'); |
@@ -114,9 +114,7 @@ class HomePageScaffold extends StatelessWidget { | @@ -114,9 +114,7 @@ class HomePageScaffold extends StatelessWidget { | ||
114 | onPressed: () { | 114 | onPressed: () { |
115 | Navigator.of(context).push( | 115 | Navigator.of(context).push( |
116 | MaterialPageRoute(builder: (context) { | 116 | MaterialPageRoute(builder: (context) { |
117 | - return ScreenUtilInit(builder: (context) { | ||
118 | - return HomePageScaffold(title: title); | ||
119 | - }); | 117 | + return const HomePageScaffold(); |
120 | }), | 118 | }), |
121 | ); | 119 | ); |
122 | }, | 120 | }, |
@@ -9,7 +9,7 @@ class MyApp extends StatelessWidget { | @@ -9,7 +9,7 @@ class MyApp extends StatelessWidget { | ||
9 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
10 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it | 10 | // In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it |
11 | return ScreenUtilInit( | 11 | return ScreenUtilInit( |
12 | - builder: (child) { | 12 | + builder: (_, child) { |
13 | return MaterialApp( | 13 | return MaterialApp( |
14 | debugShowCheckedModeBanner: false, | 14 | debugShowCheckedModeBanner: false, |
15 | title: '第一种方法', | 15 | title: '第一种方法', |
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | 5 | ||
6 | import 'dart:math' show min, max; | 6 | import 'dart:math' show min, max; |
7 | import 'dart:ui' show FlutterWindow; | 7 | import 'dart:ui' show FlutterWindow; |
8 | +import 'dart:async' show Completer; | ||
8 | 9 | ||
9 | import 'package:flutter/widgets.dart'; | 10 | import 'package:flutter/widgets.dart'; |
10 | 11 | ||
@@ -78,10 +79,8 @@ class ScreenUtil { | @@ -78,10 +79,8 @@ class ScreenUtil { | ||
78 | BuildContext context, [ | 79 | BuildContext context, [ |
79 | bool withDescendants = false, | 80 | bool withDescendants = false, |
80 | ]) { | 81 | ]) { |
81 | - final instance = ScreenUtil(); | ||
82 | - (instance._elementsToRebuild ??= {}).add(context as Element); | 82 | + (_instance._elementsToRebuild ??= {}).add(context as Element); |
83 | 83 | ||
84 | - // MediaQuery.maybeOf(context); | ||
85 | if (withDescendants) { | 84 | if (withDescendants) { |
86 | context.visitChildren((element) { | 85 | context.visitChildren((element) { |
87 | registerToBuild(element, true); | 86 | registerToBuild(element, true); |
@@ -90,25 +89,27 @@ class ScreenUtil { | @@ -90,25 +89,27 @@ class ScreenUtil { | ||
90 | } | 89 | } |
91 | 90 | ||
92 | /// Initializing the library. | 91 | /// Initializing the library. |
93 | - static void init( | ||
94 | - BuildContext? context, { | ||
95 | - Orientation? orientation, | ||
96 | - Size? deviceSize, | 92 | + static Future<void> init( |
93 | + BuildContext context, { | ||
97 | Size designSize = defaultSize, | 94 | Size designSize = defaultSize, |
98 | bool splitScreenMode = false, | 95 | bool splitScreenMode = false, |
99 | bool minTextAdapt = false, | 96 | bool minTextAdapt = false, |
100 | - }) { | 97 | + }) async { |
98 | + final navigatorContext = Navigator.maybeOf(context)?.context as Element?; | ||
101 | final mediaQueryContext = | 99 | final mediaQueryContext = |
102 | - context?.getElementForInheritedWidgetOfExactType<MediaQuery>(); | 100 | + navigatorContext?.getElementForInheritedWidgetOfExactType<MediaQuery>(); |
103 | 101 | ||
104 | - final deviceData = mediaQueryContext != null | ||
105 | - ? MediaQuery.of(context!).nonEmptySizeOrNull() | ||
106 | - : null; | 102 | + final initCompleter = Completer<void>(); |
107 | 103 | ||
108 | - mediaQueryContext?.visitChildren((el) => context = el); | 104 | + WidgetsBinding.instance.addPostFrameCallback((_) { |
105 | + mediaQueryContext?.visitChildElements((el) => _instance._context = el); | ||
106 | + if (_instance._context != null) initCompleter.complete(); | ||
107 | + }); | ||
108 | + | ||
109 | + final deviceData = MediaQuery.maybeOf(context).nonEmptySizeOrNull(); | ||
109 | 110 | ||
110 | - deviceSize ??= deviceData?.size ?? designSize; | ||
111 | - orientation ??= deviceData?.orientation ?? | 111 | + final deviceSize = deviceData?.size ?? designSize; |
112 | + final orientation = deviceData?.orientation ?? | ||
112 | (deviceSize.width > deviceSize.height | 113 | (deviceSize.width > deviceSize.height |
113 | ? Orientation.landscape | 114 | ? Orientation.landscape |
114 | : Orientation.portrait); | 115 | : Orientation.portrait); |
@@ -119,10 +120,11 @@ class ScreenUtil { | @@ -119,10 +120,11 @@ class ScreenUtil { | ||
119 | .._minTextAdapt = minTextAdapt | 120 | .._minTextAdapt = minTextAdapt |
120 | .._orientation = orientation | 121 | .._orientation = orientation |
121 | .._screenWidth = deviceSize.width | 122 | .._screenWidth = deviceSize.width |
122 | - .._screenHeight = deviceSize.height | ||
123 | - .._context = context; | 123 | + .._screenHeight = deviceSize.height; |
124 | 124 | ||
125 | _instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild()); | 125 | _instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild()); |
126 | + | ||
127 | + return initCompleter.future; | ||
126 | } | 128 | } |
127 | 129 | ||
128 | ///获取屏幕方向 | 130 | ///获取屏幕方向 |
@@ -4,26 +4,45 @@ import 'screen_util.dart'; | @@ -4,26 +4,45 @@ import 'screen_util.dart'; | ||
4 | 4 | ||
5 | typedef RebuildFactor = bool Function(MediaQueryData old, MediaQueryData data); | 5 | typedef RebuildFactor = bool Function(MediaQueryData old, MediaQueryData data); |
6 | 6 | ||
7 | -bool defaultRebuildFactor(old, data) => old.size != data.size; | 7 | +typedef ScreenUtilInitBuilder = Widget Function( |
8 | + BuildContext context, | ||
9 | + Widget? child, | ||
10 | +); | ||
11 | + | ||
12 | +class RebuildFactors { | ||
13 | + const RebuildFactors._(); | ||
14 | + | ||
15 | + static bool size(MediaQueryData old, MediaQueryData data) { | ||
16 | + return old.size != data.size; | ||
17 | + } | ||
18 | + | ||
19 | + static bool orientation(MediaQueryData old, MediaQueryData data) { | ||
20 | + return old.orientation != data.orientation; | ||
21 | + } | ||
22 | + | ||
23 | + static bool sizeAndViewInsets(MediaQueryData old, MediaQueryData data) { | ||
24 | + return old.viewInsets != data.viewInsets; | ||
25 | + } | ||
26 | + | ||
27 | + static bool all(MediaQueryData old, MediaQueryData data) { | ||
28 | + return old != data; | ||
29 | + } | ||
30 | +} | ||
8 | 31 | ||
9 | class ScreenUtilInit extends StatefulWidget { | 32 | class ScreenUtilInit extends StatefulWidget { |
10 | /// A helper widget that initializes [ScreenUtil] | 33 | /// A helper widget that initializes [ScreenUtil] |
11 | const ScreenUtilInit({ | 34 | const ScreenUtilInit({ |
12 | Key? key, | 35 | Key? key, |
13 | - this.builder, | 36 | + required this.builder, |
14 | this.child, | 37 | this.child, |
15 | - this.rebuildFactor = defaultRebuildFactor, | 38 | + this.rebuildFactor = RebuildFactors.size, |
16 | this.designSize = ScreenUtil.defaultSize, | 39 | this.designSize = ScreenUtil.defaultSize, |
17 | this.splitScreenMode = false, | 40 | this.splitScreenMode = false, |
18 | this.minTextAdapt = false, | 41 | this.minTextAdapt = false, |
19 | this.useInheritedMediaQuery = false, | 42 | this.useInheritedMediaQuery = false, |
20 | - }) : assert( | ||
21 | - builder != null || child != null, | ||
22 | - 'You must either pass builder or child or both', | ||
23 | - ), | ||
24 | - super(key: key); | 43 | + }) : super(key: key); |
25 | 44 | ||
26 | - final Widget Function(Widget? child)? builder; | 45 | + final ScreenUtilInitBuilder builder; |
27 | final Widget? child; | 46 | final Widget? child; |
28 | final bool splitScreenMode; | 47 | final bool splitScreenMode; |
29 | final bool minTextAdapt; | 48 | final bool minTextAdapt; |
@@ -40,6 +59,7 @@ class ScreenUtilInit extends StatefulWidget { | @@ -40,6 +59,7 @@ class ScreenUtilInit extends StatefulWidget { | ||
40 | class _ScreenUtilInitState extends State<ScreenUtilInit> | 59 | class _ScreenUtilInitState extends State<ScreenUtilInit> |
41 | with WidgetsBindingObserver { | 60 | with WidgetsBindingObserver { |
42 | late MediaQueryData mediaQueryData; | 61 | late MediaQueryData mediaQueryData; |
62 | + | ||
43 | bool wrappedInMediaQuery = false; | 63 | bool wrappedInMediaQuery = false; |
44 | 64 | ||
45 | WidgetsBinding get binding => WidgetsFlutterBinding.ensureInitialized(); | 65 | WidgetsBinding get binding => WidgetsFlutterBinding.ensureInitialized(); |
@@ -60,16 +80,12 @@ class _ScreenUtilInitState extends State<ScreenUtilInit> | @@ -60,16 +80,12 @@ class _ScreenUtilInitState extends State<ScreenUtilInit> | ||
60 | } | 80 | } |
61 | 81 | ||
62 | Widget get child { | 82 | Widget get child { |
63 | - return SizedBox( | ||
64 | - key: GlobalObjectKey( | ||
65 | - hashValues( | ||
66 | - this, | ||
67 | - mediaQueryData.size.width, | ||
68 | - mediaQueryData.size.height, | ||
69 | - ), | ||
70 | - ), | ||
71 | - child: widget.builder?.call(widget.child) ?? widget.child!, | ||
72 | - ); | 83 | + return widget.builder.call(context, widget.child); |
84 | + } | ||
85 | + | ||
86 | + _updateTree(Element el) { | ||
87 | + el.markNeedsBuild(); | ||
88 | + el.visitChildren(_updateTree); | ||
73 | } | 89 | } |
74 | 90 | ||
75 | @override | 91 | @override |
@@ -84,7 +100,10 @@ class _ScreenUtilInitState extends State<ScreenUtilInit> | @@ -84,7 +100,10 @@ class _ScreenUtilInitState extends State<ScreenUtilInit> | ||
84 | final old = mediaQueryData; | 100 | final old = mediaQueryData; |
85 | final data = newData; | 101 | final data = newData; |
86 | 102 | ||
87 | - if (widget.rebuildFactor(old, data)) setState(() => mediaQueryData = data); | 103 | + if (widget.rebuildFactor(old, data)) { |
104 | + mediaQueryData = data; | ||
105 | + _updateTree(context as Element); | ||
106 | + } | ||
88 | } | 107 | } |
89 | 108 | ||
90 | @override | 109 | @override |
-
Please register or login to post a comment