Mounir-Bouaiche

Fix #362 & add BuildContext to builder parameters

... ... @@ -9,9 +9,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
// In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
return ScreenUtilInit(
builder: (child) {
builder: (_, child) {
return MaterialApp(
key: const GlobalObjectKey('screen-util'),
debugShowCheckedModeBanner: false,
title: 'First Method',
// You can use the library anywhere in the app even in theme
... ...
... ... @@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class HomePageScaffold extends StatelessWidget {
const HomePageScaffold({Key? key, required this.title}) : super(key: key);
const HomePageScaffold({Key? key, this.title = ''}) : super(key: key);
void printScreenInformation() {
print('Device Size:${Size(1.sw, 1.sh)}');
... ... @@ -114,9 +114,7 @@ class HomePageScaffold extends StatelessWidget {
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return ScreenUtilInit(builder: (context) {
return HomePageScaffold(title: title);
});
return const HomePageScaffold();
}),
);
},
... ...
... ... @@ -9,7 +9,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
// In first method you only need to wrap [MaterialApp] with [ScreenUtilInit] and that's it
return ScreenUtilInit(
builder: (child) {
builder: (_, child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: '第一种方法',
... ...
... ... @@ -5,6 +5,7 @@
import 'dart:math' show min, max;
import 'dart:ui' show FlutterWindow;
import 'dart:async' show Completer;
import 'package:flutter/widgets.dart';
... ... @@ -78,10 +79,8 @@ class ScreenUtil {
BuildContext context, [
bool withDescendants = false,
]) {
final instance = ScreenUtil();
(instance._elementsToRebuild ??= {}).add(context as Element);
(_instance._elementsToRebuild ??= {}).add(context as Element);
// MediaQuery.maybeOf(context);
if (withDescendants) {
context.visitChildren((element) {
registerToBuild(element, true);
... ... @@ -90,25 +89,27 @@ class ScreenUtil {
}
/// Initializing the library.
static void init(
BuildContext? context, {
Orientation? orientation,
Size? deviceSize,
static Future<void> init(
BuildContext context, {
Size designSize = defaultSize,
bool splitScreenMode = false,
bool minTextAdapt = false,
}) {
}) async {
final navigatorContext = Navigator.maybeOf(context)?.context as Element?;
final mediaQueryContext =
context?.getElementForInheritedWidgetOfExactType<MediaQuery>();
navigatorContext?.getElementForInheritedWidgetOfExactType<MediaQuery>();
final deviceData = mediaQueryContext != null
? MediaQuery.of(context!).nonEmptySizeOrNull()
: null;
final initCompleter = Completer<void>();
mediaQueryContext?.visitChildren((el) => context = el);
WidgetsBinding.instance.addPostFrameCallback((_) {
mediaQueryContext?.visitChildElements((el) => _instance._context = el);
if (_instance._context != null) initCompleter.complete();
});
deviceSize ??= deviceData?.size ?? designSize;
orientation ??= deviceData?.orientation ??
final deviceData = MediaQuery.maybeOf(context).nonEmptySizeOrNull();
final deviceSize = deviceData?.size ?? designSize;
final orientation = deviceData?.orientation ??
(deviceSize.width > deviceSize.height
? Orientation.landscape
: Orientation.portrait);
... ... @@ -119,10 +120,11 @@ class ScreenUtil {
.._minTextAdapt = minTextAdapt
.._orientation = orientation
.._screenWidth = deviceSize.width
.._screenHeight = deviceSize.height
.._context = context;
.._screenHeight = deviceSize.height;
_instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild());
return initCompleter.future;
}
///获取屏幕方向
... ...
... ... @@ -4,26 +4,45 @@ import 'screen_util.dart';
typedef RebuildFactor = bool Function(MediaQueryData old, MediaQueryData data);
bool defaultRebuildFactor(old, data) => old.size != data.size;
typedef ScreenUtilInitBuilder = Widget Function(
BuildContext context,
Widget? child,
);
class RebuildFactors {
const RebuildFactors._();
static bool size(MediaQueryData old, MediaQueryData data) {
return old.size != data.size;
}
static bool orientation(MediaQueryData old, MediaQueryData data) {
return old.orientation != data.orientation;
}
static bool sizeAndViewInsets(MediaQueryData old, MediaQueryData data) {
return old.viewInsets != data.viewInsets;
}
static bool all(MediaQueryData old, MediaQueryData data) {
return old != data;
}
}
class ScreenUtilInit extends StatefulWidget {
/// A helper widget that initializes [ScreenUtil]
const ScreenUtilInit({
Key? key,
this.builder,
required this.builder,
this.child,
this.rebuildFactor = defaultRebuildFactor,
this.rebuildFactor = RebuildFactors.size,
this.designSize = ScreenUtil.defaultSize,
this.splitScreenMode = false,
this.minTextAdapt = false,
this.useInheritedMediaQuery = false,
}) : assert(
builder != null || child != null,
'You must either pass builder or child or both',
),
super(key: key);
}) : super(key: key);
final Widget Function(Widget? child)? builder;
final ScreenUtilInitBuilder builder;
final Widget? child;
final bool splitScreenMode;
final bool minTextAdapt;
... ... @@ -40,6 +59,7 @@ class ScreenUtilInit extends StatefulWidget {
class _ScreenUtilInitState extends State<ScreenUtilInit>
with WidgetsBindingObserver {
late MediaQueryData mediaQueryData;
bool wrappedInMediaQuery = false;
WidgetsBinding get binding => WidgetsFlutterBinding.ensureInitialized();
... ... @@ -60,16 +80,12 @@ class _ScreenUtilInitState extends State<ScreenUtilInit>
}
Widget get child {
return SizedBox(
key: GlobalObjectKey(
hashValues(
this,
mediaQueryData.size.width,
mediaQueryData.size.height,
),
),
child: widget.builder?.call(widget.child) ?? widget.child!,
);
return widget.builder.call(context, widget.child);
}
_updateTree(Element el) {
el.markNeedsBuild();
el.visitChildren(_updateTree);
}
@override
... ... @@ -84,7 +100,10 @@ class _ScreenUtilInitState extends State<ScreenUtilInit>
final old = mediaQueryData;
final data = newData;
if (widget.rebuildFactor(old, data)) setState(() => mediaQueryData = data);
if (widget.rebuildFactor(old, data)) {
mediaQueryData = data;
_updateTree(context as Element);
}
}
@override
... ...