diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 8d4492f..9625e10 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index a986b59..7374b69 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -272,7 +272,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -350,7 +350,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -399,7 +399,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/example/lib/main.dart b/example/lib/main.dart index 85266e2..4e0c334 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -115,7 +115,6 @@ class _MyHomePageState extends State { _timer?.cancel(); await EasyLoading.show( status: 'loading...', - maskType: EasyLoadingMaskType.black, ); print('EasyLoading show'); }, @@ -228,6 +227,10 @@ class _MyHomePageState extends State { padding: EdgeInsets.all(5.0), child: Text('custom'), ), + EasyLoadingMaskType.blur: Padding( + padding: EdgeInsets.all(5.0), + child: Text('blur'), + ), }, onValueChanged: (value) { EasyLoading.instance.maskType = value; diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..052974e --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,161 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_easyloading: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "3.0.5" + flutter_spinkit: + dependency: transitive + description: + name: flutter_spinkit + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.12" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.12" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" +sdks: + dart: ">=2.17.0-0 <3.0.0" + flutter: ">=2.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 2125937..a86c510 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,5 +1,6 @@ name: example description: A new Flutter project. +publish_to: none # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -20,7 +21,9 @@ dependencies: flutter: sdk: flutter - flutter_easyloading: ^3.0.0 + # flutter_easyloading: ^3.0.0 + flutter_easyloading: + path: ../ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/lib/src/easy_loading.dart b/lib/src/easy_loading.dart index 1193f48..d0e5126 100644 --- a/lib/src/easy_loading.dart +++ b/lib/src/easy_loading.dart @@ -65,6 +65,7 @@ enum EasyLoadingMaskType { clear, black, custom, + blur, } /// loading indicator type. see [https://github.com/jogboms/flutter_spinkit#-showcase] @@ -112,6 +113,12 @@ class EasyLoading { /// loading mask type, default [EasyLoadingMaskType.none]. late EasyLoadingMaskType maskType; + /// Value of blur mask, default 5.0. + late double sigmaX; + + /// Value of blur mask, default 5.0. + late double sigmaY; + /// toast position, default [EasyLoadingToastPosition.center]. late EasyLoadingToastPosition toastPosition; @@ -190,6 +197,12 @@ class EasyLoading { /// info widget of loading Widget? infoWidget; + /// padding of mask, default 0. + EdgeInsets? maskPadding; + + /// activate safe area of mask, default false. + bool? maskUseSafeArea; + Widget? _w; EasyLoadingOverlayEntry? overlayEntry; @@ -217,6 +230,8 @@ class EasyLoading { textAlign = TextAlign.center; indicatorSize = 40.0; radius = 5.0; + sigmaX = 5.0; + sigmaY = 5.0; fontSize = 15.0; progressWidth = 2.0; lineWidth = 4.0; @@ -227,6 +242,8 @@ class EasyLoading { vertical: 15.0, horizontal: 20.0, ); + maskPadding = EdgeInsets.zero; + maskUseSafeArea = false; } static EasyLoading get instance => _instance; @@ -251,6 +268,8 @@ class EasyLoading { Widget? indicator, EasyLoadingMaskType? maskType, bool? dismissOnTap, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) { Widget w = indicator ?? (_instance.indicatorWidget ?? LoadingIndicator()); return _instance._show( @@ -258,6 +277,8 @@ class EasyLoading { maskType: maskType, dismissOnTap: dismissOnTap, w: w, + maskPadding: maskPadding, + maskUseSafeArea: maskUseSafeArea, ); } @@ -266,6 +287,8 @@ class EasyLoading { double value, { String? status, EasyLoadingMaskType? maskType, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) async { assert( value >= 0.0 && value <= 1.0, @@ -292,6 +315,8 @@ class EasyLoading { maskType: maskType, dismissOnTap: false, w: w, + maskPadding: maskPadding, + maskUseSafeArea: maskUseSafeArea, ); _instance._progressKey = _progressKey; } @@ -307,6 +332,8 @@ class EasyLoading { Duration? duration, EasyLoadingMaskType? maskType, bool? dismissOnTap, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) { Widget w = _instance.successWidget ?? Icon( @@ -320,6 +347,8 @@ class EasyLoading { maskType: maskType, dismissOnTap: dismissOnTap, w: w, + maskPadding: maskPadding, + maskUseSafeArea: maskUseSafeArea, ); } @@ -329,6 +358,8 @@ class EasyLoading { Duration? duration, EasyLoadingMaskType? maskType, bool? dismissOnTap, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) { Widget w = _instance.errorWidget ?? Icon( @@ -342,6 +373,8 @@ class EasyLoading { maskType: maskType, dismissOnTap: dismissOnTap, w: w, + maskPadding: maskPadding, + maskUseSafeArea: maskUseSafeArea, ); } @@ -351,6 +384,8 @@ class EasyLoading { Duration? duration, EasyLoadingMaskType? maskType, bool? dismissOnTap, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) { Widget w = _instance.infoWidget ?? Icon( @@ -364,6 +399,8 @@ class EasyLoading { maskType: maskType, dismissOnTap: dismissOnTap, w: w, + maskPadding: maskPadding, + maskUseSafeArea: maskUseSafeArea, ); } @@ -420,6 +457,8 @@ class EasyLoading { EasyLoadingMaskType? maskType, bool? dismissOnTap, EasyLoadingToastPosition? toastPosition, + EdgeInsets? maskPadding, + bool? maskUseSafeArea, }) async { assert( overlayEntry != null, @@ -471,7 +510,11 @@ class EasyLoading { toastPosition: toastPosition, maskType: maskType, dismissOnTap: dismissOnTap, + sigmaX: sigmaX, + sigmaY: sigmaY, completer: completer, + padding: maskPadding ?? this.maskPadding, + useSafeArea: maskUseSafeArea ?? this.maskUseSafeArea ?? false, ); completer.future.whenComplete(() { _callback(EasyLoadingStatus.show); diff --git a/lib/src/widgets/container.dart b/lib/src/widgets/container.dart index 8cd8cbf..82e9d3b 100644 --- a/lib/src/widgets/container.dart +++ b/lib/src/widgets/container.dart @@ -21,6 +21,7 @@ // IN THE SOFTWARE. import 'dart:async'; +import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -39,6 +40,10 @@ class EasyLoadingContainer extends StatefulWidget { final EasyLoadingMaskType? maskType; final Completer? completer; final bool animation; + final double sigmaX; + final double sigmaY; + final EdgeInsetsGeometry? padding; + final bool useSafeArea; const EasyLoadingContainer({ Key? key, @@ -48,7 +53,11 @@ class EasyLoadingContainer extends StatefulWidget { this.toastPosition, this.maskType, this.completer, + required this.sigmaX, + required this.sigmaY, this.animation = true, + this.useSafeArea = false, + this.padding, }) : super(key: key); @override @@ -62,6 +71,7 @@ class EasyLoadingContainerState extends State late AnimationController _animationController; late AlignmentGeometry _alignment; late bool _dismissOnTap, _ignoring; + late EasyLoadingMaskType? _maskType; //https://docs.flutter.dev/development/tools/sdk/release-notes/release-notes-3.0.0 bool get isPersistentCallbacks => @@ -78,9 +88,9 @@ class EasyLoadingContainerState extends State : AlignmentDirectional.center; _dismissOnTap = widget.dismissOnTap ?? (EasyLoadingTheme.dismissOnTap ?? false); - _ignoring = - _dismissOnTap ? false : EasyLoadingTheme.ignoring(widget.maskType); - _maskColor = EasyLoadingTheme.maskColor(widget.maskType); + _maskType = widget.maskType; + _ignoring = _dismissOnTap ? false : EasyLoadingTheme.ignoring(_maskType); + _maskColor = EasyLoadingTheme.maskColor(_maskType); _animationController = AnimationController( vsync: this, duration: EasyLoadingTheme.animationDuration, @@ -102,9 +112,11 @@ class EasyLoadingContainerState extends State Future show(bool animation) { if (isPersistentCallbacks) { Completer completer = Completer(); + _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback((_) => completer .complete(_animationController.forward(from: animation ? 0 : 1))); + return completer.future; } else { return _animationController.forward(from: animation ? 0 : 1); @@ -114,9 +126,11 @@ class EasyLoadingContainerState extends State Future dismiss(bool animation) { if (isPersistentCallbacks) { Completer completer = Completer(); + _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback((_) => completer .complete(_animationController.reverse(from: animation ? 1 : 0))); + return completer.future; } else { return _animationController.reverse(from: animation ? 1 : 0); @@ -136,35 +150,46 @@ class EasyLoadingContainerState extends State @override Widget build(BuildContext context) { + final background = AnimatedBuilder( + animation: _animationController, + builder: (BuildContext context, Widget? child) { + return Opacity( + opacity: _animationController.value, + child: IgnorePointer( + ignoring: _ignoring, + child: Container( + color: Colors.transparent, + child: Padding( + padding: widget.padding ?? EdgeInsets.zero, + child: Container( + color: Colors.transparent, + child: _dismissOnTap + ? GestureDetector( + onTap: _onTap, + behavior: HitTestBehavior.translucent, + child: _buildMaskContainerByMaskType(), + ) + : _buildMaskContainerByMaskType(), + ), + ), + ), + ), + ); + }, + ); + + Widget withSafeArea = background; + + if (widget.useSafeArea) { + withSafeArea = SafeArea( + child: background, + ); + } + return Stack( alignment: _alignment, children: [ - AnimatedBuilder( - animation: _animationController, - builder: (BuildContext context, Widget? child) { - return Opacity( - opacity: _animationController.value, - child: IgnorePointer( - ignoring: _ignoring, - child: _dismissOnTap - ? GestureDetector( - onTap: _onTap, - behavior: HitTestBehavior.translucent, - child: Container( - width: double.infinity, - height: double.infinity, - color: _maskColor, - ), - ) - : Container( - width: double.infinity, - height: double.infinity, - color: _maskColor, - ), - ), - ); - }, - ), + withSafeArea, AnimatedBuilder( animation: _animationController, builder: (BuildContext context, Widget? child) { @@ -181,6 +206,27 @@ class EasyLoadingContainerState extends State ], ); } + + Widget _buildMaskContainerByMaskType() { + if (_maskType == EasyLoadingMaskType.blur) + return ClipRect( + child: BackdropFilter( + filter: + ImageFilter.blur(sigmaX: widget.sigmaX, sigmaY: widget.sigmaY), + child: _buildMaskContainer(), + ), + ); + + return _buildMaskContainer(); + } + + Container _buildMaskContainer() { + return Container( + width: double.infinity, + height: double.infinity, + color: _maskColor, + ); + } } class _Indicator extends StatelessWidget { @@ -196,13 +242,15 @@ class _Indicator extends StatelessWidget { Widget build(BuildContext context) { return Container( margin: const EdgeInsets.all(50.0), - decoration: BoxDecoration( - color: EasyLoadingTheme.backgroundColor, - borderRadius: BorderRadius.circular( - EasyLoadingTheme.radius, - ), - boxShadow: EasyLoadingTheme.boxShadow, - ), + decoration: EasyLoadingTheme.backgroundColor == Colors.transparent + ? null + : BoxDecoration( + color: EasyLoadingTheme.backgroundColor, + borderRadius: BorderRadius.circular( + EasyLoadingTheme.radius, + ), + boxShadow: EasyLoadingTheme.boxShadow, + ), padding: EasyLoadingTheme.contentPadding, child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..183eb63 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,147 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_spinkit: + dependency: "direct main" + description: + name: flutter_spinkit + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.12" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.12" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" +sdks: + dart: ">=2.17.0-0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index e31e2ff..3baa042 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,9 @@ name: flutter_easyloading -description: A clean and lightweight loading/toast widget for Flutter, Easy to use without context, Support iOS、Android and Web +description: A clean and lightweight loading/toast widget for Flutter, Easy to use without context, Support iOS, Android and Web version: 3.0.5 homepage: https://github.com/nslogx/flutter_easyloading + environment: sdk: ">=2.12.0 <3.0.0"