Showing
5 changed files
with
138 additions
and
18 deletions
1 | -import 'package:flutter/widgets.dart'; | 1 | +/*import 'package:flutter/widgets.dart'; |
2 | import 'src/first_method.dart' as firstMethod; | 2 | import 'src/first_method.dart' as firstMethod; |
3 | import 'src/second_method.dart' as secondMethod; | 3 | import 'src/second_method.dart' as secondMethod; |
4 | 4 | ||
@@ -6,3 +6,106 @@ void main() { | @@ -6,3 +6,106 @@ void main() { | ||
6 | const method = int.fromEnvironment('method', defaultValue: 1); | 6 | const method = int.fromEnvironment('method', defaultValue: 1); |
7 | runApp(method == 1 ? firstMethod.MyApp() : secondMethod.MyApp()); | 7 | runApp(method == 1 ? firstMethod.MyApp() : secondMethod.MyApp()); |
8 | } | 8 | } |
9 | +*/ | ||
10 | + | ||
11 | +import 'dart:async'; | ||
12 | + | ||
13 | +import 'package:flutter/material.dart'; | ||
14 | +import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
15 | + | ||
16 | +void main() { | ||
17 | + runApp(ScreenUtilInit( | ||
18 | + builder: (child) => MaterialApp( | ||
19 | + key: GlobalObjectKey('screenutil'), | ||
20 | + theme: ThemeData( | ||
21 | + textTheme: TextTheme( | ||
22 | + bodyText2: TextStyle(fontSize: 32.sp), | ||
23 | + ), | ||
24 | + ), | ||
25 | + home: child, | ||
26 | + ), | ||
27 | + child: ThirdPage(), | ||
28 | + )); | ||
29 | +} | ||
30 | + | ||
31 | +class MyStatelessElement<T extends TestPage> extends StatelessElement { | ||
32 | + MyStatelessElement(T widget) : super(widget); | ||
33 | + | ||
34 | + @override | ||
35 | + T get widget => super.widget as T; | ||
36 | + | ||
37 | + @override | ||
38 | + void mount(Element? parent, Object? newSlot) { | ||
39 | + super.mount(parent, newSlot); | ||
40 | + print('${widget.text()} is mounted'); | ||
41 | + } | ||
42 | + | ||
43 | + @override | ||
44 | + void unmount() { | ||
45 | + print('${widget.text()} is unmounted'); | ||
46 | + super.unmount(); | ||
47 | + } | ||
48 | +} | ||
49 | + | ||
50 | +abstract class TestPage extends StatelessWidget { | ||
51 | + String text() => runtimeType.toString(); | ||
52 | + | ||
53 | + Widget goto(); | ||
54 | + | ||
55 | + @override | ||
56 | + StatelessElement createElement() => MyStatelessElement(this); | ||
57 | + | ||
58 | + @override | ||
59 | + Widget build(BuildContext context) { | ||
60 | + Timer(const Duration(seconds: 5), () { | ||
61 | + Navigator.of(context).pushAndRemoveUntil( | ||
62 | + MaterialPageRoute(builder: (context) => goto()), | ||
63 | + (route) => false, | ||
64 | + ); | ||
65 | + }); | ||
66 | + return Scaffold( | ||
67 | + body: SafeArea( | ||
68 | + child: Padding( | ||
69 | + padding: const EdgeInsets.all(20).r, | ||
70 | + child: Column( | ||
71 | + mainAxisSize: MainAxisSize.min, | ||
72 | + children: [ | ||
73 | + TextField(), | ||
74 | + Text( | ||
75 | + text(), | ||
76 | + style: TextStyle(fontSize: 32.sp), | ||
77 | + ), | ||
78 | + Text(text()), | ||
79 | + Expanded( | ||
80 | + child: ListView.separated( | ||
81 | + shrinkWrap: true, | ||
82 | + itemBuilder: (context, index) => Text('$index'), | ||
83 | + separatorBuilder: (_, __) => Container( | ||
84 | + height: 50.h, | ||
85 | + color: Colors.green, | ||
86 | + ), | ||
87 | + itemCount: 10, | ||
88 | + ), | ||
89 | + ), | ||
90 | + ], | ||
91 | + ), | ||
92 | + ), | ||
93 | + ), | ||
94 | + ); | ||
95 | + } | ||
96 | +} | ||
97 | + | ||
98 | +class FirstPage extends TestPage { | ||
99 | + @override | ||
100 | + Widget goto() => SecondPage(); | ||
101 | +} | ||
102 | + | ||
103 | +class SecondPage extends TestPage { | ||
104 | + @override | ||
105 | + Widget goto() => FirstPage(); | ||
106 | +} | ||
107 | + | ||
108 | +class ThirdPage extends TestPage { | ||
109 | + @override | ||
110 | + Widget goto() => FirstPage(); | ||
111 | +} |
@@ -9,20 +9,19 @@ class MyApp extends StatelessWidget { | @@ -9,20 +9,19 @@ 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: (context) { | 12 | + builder: (child) { |
13 | return MaterialApp( | 13 | return MaterialApp( |
14 | debugShowCheckedModeBanner: false, | 14 | debugShowCheckedModeBanner: false, |
15 | - // Use this line to prevent extra rebuilds | ||
16 | - useInheritedMediaQuery: true, | ||
17 | title: 'First Method', | 15 | title: 'First Method', |
18 | // 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 |
19 | theme: ThemeData( | 17 | theme: ThemeData( |
20 | primarySwatch: Colors.blue, | 18 | primarySwatch: Colors.blue, |
21 | textTheme: TextTheme(bodyText2: TextStyle(fontSize: 16.sp)), | 19 | textTheme: TextTheme(bodyText2: TextStyle(fontSize: 16.sp)), |
22 | ), | 20 | ), |
23 | - home: HomePage(title: 'First Method'), | 21 | + home: child, |
24 | ); | 22 | ); |
25 | }, | 23 | }, |
24 | + child: HomePage(title: 'First Method'), | ||
26 | ); | 25 | ); |
27 | } | 26 | } |
28 | } | 27 | } |
@@ -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: (context) { | 12 | + builder: (child) { |
13 | return MaterialApp( | 13 | return MaterialApp( |
14 | debugShowCheckedModeBanner: false, | 14 | debugShowCheckedModeBanner: false, |
15 | title: '第一种方法', | 15 | title: '第一种方法', |
@@ -18,9 +18,10 @@ class MyApp extends StatelessWidget { | @@ -18,9 +18,10 @@ class MyApp extends StatelessWidget { | ||
18 | primarySwatch: Colors.blue, | 18 | primarySwatch: Colors.blue, |
19 | textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)), | 19 | textTheme: TextTheme(bodyText2: TextStyle(fontSize: 30.sp)), |
20 | ), | 20 | ), |
21 | - home: HomePage(title: '第一种方法'), | 21 | + home: child, |
22 | ); | 22 | ); |
23 | }, | 23 | }, |
24 | + child: HomePage(title: '第一种方法'), | ||
24 | ); | 25 | ); |
25 | } | 26 | } |
26 | } | 27 | } |
@@ -69,8 +69,19 @@ class ScreenUtil { | @@ -69,8 +69,19 @@ class ScreenUtil { | ||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | - static void setContext(BuildContext context) { | ||
73 | - _instance.context = context; | 72 | + /// ### Experimental |
73 | + /// Register current page and all its descendants to rebuild | ||
74 | + /// Helpful when building for web and desktop | ||
75 | + static void registerToBuild( | ||
76 | + BuildContext context, [ | ||
77 | + bool withDescendants = false, | ||
78 | + ]) { | ||
79 | + MediaQuery.maybeOf(context); | ||
80 | + if (withDescendants) { | ||
81 | + (context as Element).visitChildren((element) { | ||
82 | + registerToBuild(element, true); | ||
83 | + }); | ||
84 | + } | ||
74 | } | 85 | } |
75 | 86 | ||
76 | /// Initializing the library. | 87 | /// Initializing the library. |
@@ -89,6 +100,8 @@ class ScreenUtil { | @@ -89,6 +100,8 @@ class ScreenUtil { | ||
89 | ? MediaQuery.of(context!).nonEmptySizeOrNull() | 100 | ? MediaQuery.of(context!).nonEmptySizeOrNull() |
90 | : null; | 101 | : null; |
91 | 102 | ||
103 | + mediaQueryContext?.visitChildren((el) => context = el); | ||
104 | + | ||
92 | deviceSize ??= deviceData?.size ?? designSize; | 105 | deviceSize ??= deviceData?.size ?? designSize; |
93 | orientation ??= deviceData?.orientation ?? | 106 | orientation ??= deviceData?.orientation ?? |
94 | (deviceSize.width > deviceSize.height | 107 | (deviceSize.width > deviceSize.height |
@@ -102,7 +115,7 @@ class ScreenUtil { | @@ -102,7 +115,7 @@ class ScreenUtil { | ||
102 | .._orientation = orientation | 115 | .._orientation = orientation |
103 | .._screenWidth = deviceSize.width | 116 | .._screenWidth = deviceSize.width |
104 | .._screenHeight = deviceSize.height | 117 | .._screenHeight = deviceSize.height |
105 | - ..context = mediaQueryContext; | 118 | + ..context = mediaQueryContext != null ? context : null; |
106 | } | 119 | } |
107 | 120 | ||
108 | ///获取屏幕方向 | 121 | ///获取屏幕方向 |
@@ -6,14 +6,16 @@ import 'screen_util.dart'; | @@ -6,14 +6,16 @@ import 'screen_util.dart'; | ||
6 | class ScreenUtilInit extends StatelessWidget { | 6 | class ScreenUtilInit extends StatelessWidget { |
7 | /// A helper widget that initializes [ScreenUtil] | 7 | /// A helper widget that initializes [ScreenUtil] |
8 | const ScreenUtilInit({ | 8 | const ScreenUtilInit({ |
9 | - required this.builder, | 9 | + this.builder, |
10 | + this.child, | ||
10 | this.designSize = ScreenUtil.defaultSize, | 11 | this.designSize = ScreenUtil.defaultSize, |
11 | this.splitScreenMode = false, | 12 | this.splitScreenMode = false, |
12 | this.minTextAdapt = false, | 13 | this.minTextAdapt = false, |
13 | Key? key, | 14 | Key? key, |
14 | }) : super(key: key); | 15 | }) : super(key: key); |
15 | 16 | ||
16 | - final WidgetBuilder builder; | 17 | + final Widget Function(Widget? child)? builder; |
18 | + final Widget? child; | ||
17 | final bool splitScreenMode; | 19 | final bool splitScreenMode; |
18 | final bool minTextAdapt; | 20 | final bool minTextAdapt; |
19 | 21 | ||
@@ -25,11 +27,13 @@ class ScreenUtilInit extends StatelessWidget { | @@ -25,11 +27,13 @@ class ScreenUtilInit extends StatelessWidget { | ||
25 | bool firstFrameAllowed = false; | 27 | bool firstFrameAllowed = false; |
26 | RendererBinding.instance!.deferFirstFrame(); | 28 | RendererBinding.instance!.deferFirstFrame(); |
27 | 29 | ||
28 | - return MediaQuery.fromWindow( | ||
29 | - child: Builder(builder: (context) { | ||
30 | - if (MediaQuery.of(context).size == Size.zero) return const SizedBox(); | 30 | + return LayoutBuilder( |
31 | + builder: (context, constraints) { | ||
32 | + if (constraints.biggest == Size.zero) return const SizedBox.shrink(); | ||
33 | + | ||
31 | ScreenUtil.init( | 34 | ScreenUtil.init( |
32 | - context, | 35 | + null, |
36 | + deviceSize: constraints.biggest, | ||
33 | designSize: designSize, | 37 | designSize: designSize, |
34 | splitScreenMode: splitScreenMode, | 38 | splitScreenMode: splitScreenMode, |
35 | minTextAdapt: minTextAdapt, | 39 | minTextAdapt: minTextAdapt, |
@@ -40,8 +44,8 @@ class ScreenUtilInit extends StatelessWidget { | @@ -40,8 +44,8 @@ class ScreenUtilInit extends StatelessWidget { | ||
40 | firstFrameAllowed = true; | 44 | firstFrameAllowed = true; |
41 | } | 45 | } |
42 | 46 | ||
43 | - return builder(context); | ||
44 | - }), | 47 | + return builder?.call(child) ?? child!; |
48 | + }, | ||
45 | ); | 49 | ); |
46 | } | 50 | } |
47 | } | 51 | } |
-
Please register or login to post a comment