Skip to content

Commit

Permalink
Clean codes & add features & fix bugs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Mounir Bouaiche committed Jun 10, 2023
1 parent de2df4f commit 8552509
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 186 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,6 @@ doc
.lock
coverage*
*.lock

# Don't commit .fvm directory containing machine-specific symlink to sdk & flutter version
**/.fvm
11 changes: 11 additions & 0 deletions example/lib/responsive_widgets.g.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/////////////////////////////////////////////////////////////////////////
/// Generated via plugin: flutter_screenutil_generator - Do Not Touch ///
/////////////////////////////////////////////////////////////////////////
part of 'responsive_widgets.su.dart';

const _responsiveWidgets = {
'MyThemedApp',
'MyApp',
'HomePageScaffold',
};
3 changes: 3 additions & 0 deletions example/lib/responsive_widgets.su.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
part 'responsive_widgets.g.dart';

get responsiveWidgets => _responsiveWidgets;
31 changes: 15 additions & 16 deletions example/lib/src/first_method.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:example/responsive_widgets.su.dart';
import 'package:example/src/home.dart';
import 'package:flutter/material.dart';
// import 'package:example/allowed_classes.su.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class MyApp extends StatelessWidget {
Expand All @@ -9,22 +11,19 @@ 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(
useInheritedMediaQuery: false,
builder: (_, child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'First Method',
// You can use the library anywhere in the app even in theme
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: Typography(platform: TargetPlatform.iOS)
.black
.apply(fontSizeFactor: 1),
),
home: child,
);
},
child: const HomePage(title: 'First Method'),
responsiveWidgets: responsiveWidgets,
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'First Method',
// You can use the library anywhere in the app even in theme
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: Typography(platform: TargetPlatform.iOS)
.black
.apply(fontSizeFactor: 1),
),
home: const HomePage(title: 'First Method'),
),
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/lib/src/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class HomePageScaffold extends StatelessWidget {
class HomePageScaffold extends StatelessWidget with SU {
const HomePageScaffold({Key? key, this.title = ''}) : super(key: key);

void printScreenInformation(BuildContext context) {
Expand Down
5 changes: 4 additions & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ dev_dependencies:
flutter_test:
sdk: flutter
test: ^1.15.7
build_runner:
flutter_screenutil_generator:
path: ../../flutter_screenutil_generator

flutter:
uses-material-design: true
uses-material-design: true
1 change: 1 addition & 0 deletions lib/flutter_screenutil.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export 'src/r_sizedbox.dart';
export 'src/screen_util.dart';
export 'src/screenutil_init.dart';
export 'src/size_extension.dart';
export 'src/screenutil_mixin.dart';
106 changes: 53 additions & 53 deletions lib/src/screen_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
*/

import 'dart:math' show min, max;
import 'dart:ui' show FlutterView;
import 'dart:async' show Completer;
import 'dart:ui' as ui show FlutterView;

import 'package:flutter/widgets.dart';

Expand All @@ -20,10 +19,8 @@ class ScreenUtil {
///屏幕方向
late Orientation _orientation;

late double _screenWidth;
late double _screenHeight;
late bool _minTextAdapt;
BuildContext? _context;
late MediaQueryData _data;
late bool _splitScreenMode;

ScreenUtil._();
Expand All @@ -32,6 +29,22 @@ class ScreenUtil {
return _instance;
}

factory ScreenUtil.init(
BuildContext context, {
Size designSize = defaultSize,
bool splitScreenMode = false,
bool minTextAdapt = false,
}) {
configure(
data: MediaQuery.maybeOf(context),
designSize: designSize,
minTextAdapt: minTextAdapt,
splitScreenMode: splitScreenMode,
);

return _instance;
}

/// Manually wait for window size to be initialized
///
/// `Recommended` to use before you need access window size
Expand All @@ -55,19 +68,25 @@ class ScreenUtil {
/// )
/// ```
static Future<void> ensureScreenSize([
FlutterView? window,
ui.FlutterView? window,
Duration duration = const Duration(milliseconds: 10),
]) async {
final binding = WidgetsFlutterBinding.ensureInitialized();
window ??= WidgetsBinding.instance.platformDispatcher.implicitView;
binding.deferFirstFrame();

if (window?.physicalGeometry.isEmpty == true) {
return Future.delayed(duration, () async {
binding.deferFirstFrame();
await ensureScreenSize(window, duration);
return binding.allowFirstFrame();
});
}
await Future.doWhile(() {
if (window == null) {
window = binding.platformDispatcher.implicitView;
}

if (window == null || window!.physicalGeometry.isEmpty == true) {
return Future.delayed(duration, () => true);
}

return false;
});

binding.allowFirstFrame();
}

Set<Element>? _elementsToRebuild;
Expand All @@ -89,43 +108,30 @@ class ScreenUtil {
}

/// Initializing the library.
static Future<void> init(BuildContext context,
{Size designSize = defaultSize,
bool splitScreenMode = false,
bool minTextAdapt = false,
bool scaleByHeight = false}) async {
final mediaQueryContext =
context.getElementForInheritedWidgetOfExactType<MediaQuery>();

final initCompleter = Completer<void>();

WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((_) {
mediaQueryContext?.visitChildElements((el) => _instance._context = el);
if (_instance._context != null) initCompleter.complete();
});
static void configure({
MediaQueryData? data,
Size? designSize,
bool? splitScreenMode,
bool? minTextAdapt,
}) {
if (data != null) _instance._data = data;

final deviceData = _instance._data.nonEmptySizeOrNull();
final deviceSize = deviceData?.size ?? designSize ?? _instance._uiSize;

final deviceData = MediaQuery.maybeOf(context).nonEmptySizeOrNull();
if (designSize != null) _instance._uiSize = designSize;

final deviceSize = deviceData?.size ?? designSize;
final orientation = deviceData?.orientation ??
(deviceSize.width > deviceSize.height
? Orientation.landscape
: Orientation.portrait);

_instance
.._context = scaleByHeight ? null : context
.._uiSize = designSize
.._splitScreenMode = splitScreenMode
.._minTextAdapt = minTextAdapt
.._orientation = orientation
.._screenWidth = scaleByHeight
? (deviceSize.height * designSize.width) / designSize.height
: deviceSize.width
.._screenHeight = deviceSize.height;
.._minTextAdapt = minTextAdapt ?? _instance._minTextAdapt
.._splitScreenMode = splitScreenMode ?? _instance._splitScreenMode
.._orientation = orientation;

_instance._elementsToRebuild?.forEach((el) => el.markNeedsBuild());

return initCompleter.future;
}

///获取屏幕方向
Expand All @@ -134,33 +140,27 @@ class ScreenUtil {

/// 每个逻辑像素的字体像素数,字体的缩放比例
/// The number of font pixels for each logical pixel.
double get textScaleFactor =>
_context != null ? MediaQuery.of(_context!).textScaleFactor : 1;
double get textScaleFactor => _data.textScaleFactor;

/// 设备的像素密度
/// The size of the media in logical pixels (e.g, the size of the screen).
double? get pixelRatio =>
_context != null ? MediaQuery.of(_context!).devicePixelRatio : 1;
double? get pixelRatio => _data.devicePixelRatio;

/// 当前设备宽度 dp
/// The horizontal extent of this size.
double get screenWidth =>
_context != null ? MediaQuery.of(_context!).size.width : _screenWidth;
double get screenWidth => _data.size.width;

///当前设备高度 dp
///The vertical extent of this size. dp
double get screenHeight =>
_context != null ? MediaQuery.of(_context!).size.height : _screenHeight;
double get screenHeight => _data.size.height;

/// 状态栏高度 dp 刘海屏会更高
/// The offset from the top, in dp
double get statusBarHeight =>
_context == null ? 0 : MediaQuery.of(_context!).padding.top;
double get statusBarHeight => _data.padding.top;

/// 底部安全区距离 dp
/// The offset from the bottom, in dp
double get bottomBarHeight =>
_context == null ? 0 : MediaQuery.of(_context!).padding.bottom;
double get bottomBarHeight => _data.padding.bottom;

/// 实际尺寸与UI设计的比例
/// The ratio of actual width to UI design
Expand Down
Loading

0 comments on commit 8552509

Please sign in to comment.