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