diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b4f215..bdc718e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,26 +1,33 @@
-## [0.2.1] - (2021-04-02)
+## 0.3.0 (2022-03-18)
+
+- Several minor Fixes
+- Performance improvements
+- BREAKING: Changes default value of `padding` to `EdgeInsets.zero`
+- BREAKING: Changes default color to `Theme.of(context).colorScheme.secondary`
+
+## 0.2.1 (2021-04-02)
- Minor Changes/Fixes
-- Changes default values of CircularWidgetLoading
+- Changes default values of `CircularWidgetLoading`
-## [0.2.0] - (2021-03-04)
+## 0.2.0 (2021-03-04)
- Migrates to null safety
-## [0.1.2] - (2021-03-02)
+## 0.1.2 (2021-03-02)
-- Fixes key handling if animatedSize is false
+- Fixes key handling if `animatedSize` is false
- Removes warnings in code
- Improves performance
-## [0.1.1] - (2021-03-02)
+## 0.1.1 (2021-03-02)
-- Fixes key handling in CircularWidgetLoading
+- Fixes key handling in `CircularWidgetLoading`
- Adds some comments in the code
- Adds GIF in README.md
-## [0.1.0] - (2021-03-02)
+## 0.1.0 (2021-03-02)
- Initial release
-- WiperLoading
-- CircularWidgetLoading
+- `WiperLoading`
+- `CircularWidgetLoading`
diff --git a/README.md b/README.md
index 13da3ed..6e3544d 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[![likes](https://badges.bar/widget_loading/likes)](https://pub.dev/packages/widget_loading/score)
+[![popularity](https://badges.bar/widget_loading/popularity)](https://pub.dev/packages/widget_loading/score)
[![pub points](https://badges.bar/widget_loading/pub%20points)](https://pub.dev/packages/widget_loading/score)
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 6b4c0f7..f2872cf 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 8.0
+ 9.0
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 1aec2aa..9690c8f 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
@@ -127,7 +127,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1020;
+ LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 1d526a1..919434a 100644
--- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:">
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a28140c..3db53b6 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
{
),
counterCard(Curves.easeInOutCirc),
counterCard(Curves.easeInOutCirc,
- builder: (width, height) =>
- Container(width: width, height: height, decoration: BoxDecoration(color: Colors.purple, borderRadius: BorderRadius.circular(5.0))),
+ builder: (width, height) => Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(
+ color: Colors.purple,
+ borderRadius: BorderRadius.circular(5.0))),
wiperWidth: 50),
counterCard(
Curves.linear,
- builder: (width, height) =>
- Container(width: width, height: height, decoration: BoxDecoration(color: Colors.purple, borderRadius: BorderRadius.circular(5.0))),
+ builder: (width, height) => Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(
+ color: Colors.purple,
+ borderRadius: BorderRadius.circular(5.0))),
wiperWidth: 10,
deformingFactor: 0.2,
direction: WiperDirection.up,
),
- counterCard(Curves.easeInOutCirc, padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 30.0)),
+ counterCard(Curves.easeInOutCirc,
+ padding: EdgeInsets.symmetric(
+ horizontal: 15.0, vertical: 30.0)),
counterCard(Curves.easeOutSine,
builder: (width, height) => Container(
width: width,
height: height,
- decoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle),
+ decoration: BoxDecoration(
+ color: Colors.red, shape: BoxShape.circle),
),
wiperWidth: 20),
counterCard(Curves.easeOutSine,
- builder: (width, height) =>
- Container(width: width, height: height, decoration: BoxDecoration(color: Colors.purple, borderRadius: BorderRadius.circular(5.0))),
+ builder: (width, height) => Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(
+ color: Colors.purple,
+ borderRadius: BorderRadius.circular(5.0))),
wiperWidth: 20,
direction: WiperDirection.left),
counterCardCircle(Curves.linear),
@@ -171,7 +186,8 @@ class _ExampleState extends State {
);
Widget counterCardCircle(Curve curve, {WiperBuilder? builder}) => InkWell(
- onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (c) => LoadingScaffold())),
+ onTap: () => Navigator.of(context)
+ .push(MaterialPageRoute(builder: (c) => LoadingScaffold())),
child: Card(
elevation: 5.0,
child: CircularWidgetLoading(
@@ -180,7 +196,8 @@ class _ExampleState extends State {
rollingFactor: 0.8,
loading: loading,
child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 50.0),
+ padding: const EdgeInsets.symmetric(
+ horizontal: 15.0, vertical: 50.0),
child: ListTile(
leading: Text(
'Counter',
diff --git a/example/pubspec.lock b/example/pubspec.lock
index e5dd076..bc87a11 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -7,7 +7,7 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.5.0"
+ version: "2.8.2"
boolean_selector:
dependency: transitive
description:
@@ -21,14 +21,14 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0"
+ version: "1.3.1"
clock:
dependency: transitive
description:
@@ -73,14 +73,21 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.10"
+ version: "0.12.11"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.3"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.3.0"
+ version: "1.7.0"
path:
dependency: transitive
description:
@@ -99,7 +106,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
- version: "1.8.0"
+ version: "1.8.1"
stack_trace:
dependency: transitive
description:
@@ -134,7 +141,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.19"
+ version: "0.4.8"
typed_data:
dependency: transitive
description:
@@ -148,14 +155,14 @@ packages:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
widget_loading:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "0.2.1"
+ version: "0.3.0"
sdks:
- dart: ">=2.12.0 <3.0.0"
+ dart: ">=2.14.0 <3.0.0"
flutter: ">=1.17.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 8b8bc1a..579e15e 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -1,19 +1,19 @@
name: example
description: Example Project for the package widget_loading.
+publish_to: 'none'
+
version: 1.0.0+1
environment:
- sdk: ">=2.12.0-259.16.beta <3.0.0"
+ sdk: ">=2.15.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
widget_loading:
- path: ../
-
- cupertino_icons: ^1.0.0
+ path: '..'
dev_dependencies:
flutter_test:
diff --git a/lib/src/utils/extensions.dart b/lib/src/utils/extensions.dart
index 7e0fc3f..ae30a7f 100644
--- a/lib/src/utils/extensions.dart
+++ b/lib/src/utils/extensions.dart
@@ -11,11 +11,13 @@ extension Derivation on CurvedAnimation {
case AnimationStatus.forward:
double value = max(this.parent.value - dif, 0.0);
if (value == this.parent.value) return 0.0;
- return (this.value - this.curve.transform(value)) / (this.parent.value - value);
+ return (this.value - this.curve.transform(value)) /
+ (this.parent.value - value);
case AnimationStatus.reverse:
double value = min(this.parent.value + dif, 1.0);
if (value == this.parent.value) return 0.0;
- return (this.value - this.curve.transform(value)) / (value - this.parent.value);
+ return (this.value - this.curve.transform(value)) /
+ (value - this.parent.value);
case AnimationStatus.dismissed:
case AnimationStatus.completed:
break;
diff --git a/lib/src/widgets/circular_widget_loading.dart b/lib/src/widgets/circular_widget_loading.dart
index a010f98..2d95213 100644
--- a/lib/src/widgets/circular_widget_loading.dart
+++ b/lib/src/widgets/circular_widget_loading.dart
@@ -3,7 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:widget_loading/src/utils/loading_state.dart';
import 'package:widget_loading/src/widgets/loading_widget.dart';
-import 'package:widget_loading/src/widgets/widget_sized_box.dart';
+import 'package:widget_loading/src/widgets/widget_wrapper.dart';
typedef DotBuilder = Widget Function(double radius);
@@ -77,7 +77,7 @@ class CircularWidgetLoading extends StatefulWidget {
this.loadingDuration = const Duration(milliseconds: 2000),
this.appearingCurve = Curves.fastOutSlowIn,
this.loadingCurve = Curves.easeInOutCirc,
- this.padding = const EdgeInsets.all(10.0),
+ this.padding = EdgeInsets.zero,
this.dotBuilder,
this.rollingDuration = 1.0,
this.dotCount = 5,
@@ -91,15 +91,18 @@ class CircularWidgetLoading extends StatefulWidget {
_CircularWidgetLoadingState createState() => _CircularWidgetLoadingState();
}
-class _CircularWidgetLoadingState extends State with TickerProviderStateMixin, LoadingWidgetState {
+class _CircularWidgetLoadingState
+ extends LoadingWidgetState
+ with TickerProviderStateMixin {
late AnimationController _controller;
late AnimationController _appearingController;
- late Animation _appearingAnimation;
- List> _animations = [];
+ late CurvedAnimation _appearingAnimation;
+ List _animations = [];
final _childKey = GlobalKey();
+ final _animatedSizeKey = GlobalKey();
- Widget _child = Container();
+ Widget _child = SizedBox();
@override
void initState() {
@@ -109,19 +112,12 @@ class _CircularWidgetLoadingState extends State with Tick
assert(widget.rollingFactor >= 0 && widget.rollingFactor <= 1);
assert(widget.minDotRadiusFactor >= 0 && widget.minDotRadiusFactor <= 1);
- loadingState = widget.loading ? LoadingState.LOADING : LoadingState.LOADED;
-
_child = widget.child;
_appearingController = AnimationController(
duration: widget.appearingDuration,
vsync: this,
- )
- ..addListener(() {
- if (!appearing && !disappearing) return;
- setState(() {});
- })
- ..addStatusListener((status) {
+ )..addStatusListener((status) {
switch (status) {
case AnimationStatus.dismissed:
if (disappearing) {
@@ -139,17 +135,13 @@ class _CircularWidgetLoadingState extends State with Tick
}
});
- _appearingAnimation = CurvedAnimation(parent: _appearingController, curve: widget.appearingCurve);
+ _appearingAnimation = CurvedAnimation(
+ parent: _appearingController, curve: widget.appearingCurve);
_controller = AnimationController(
duration: widget.loadingDuration,
vsync: this,
- )
- ..addListener(() {
- if (!loading) return;
- setState(() {});
- })
- ..addStatusListener((status) {
+ )..addStatusListener((status) {
switch (status) {
case AnimationStatus.forward:
break;
@@ -161,19 +153,42 @@ class _CircularWidgetLoadingState extends State with Tick
if (!widget.loading && loading) {
loadingState = LoadingState.APPEARING;
_appearingController.forward(from: 0.0);
- } else
- WidgetsBinding.instance?.addPostFrameCallback((_) => _controller.forward(from: 0.0));
+ } else {
+ _controller.forward(from: 0.0);
+ }
break;
}
});
- double dif = widget.dotCount <= 1 ? 0 : widget.rollingDuration * (1 - widget.rollingFactor) / (widget.dotCount - 1);
- double singleRollingDuration = widget.rollingDuration * widget.rollingFactor;
- for (int i = 0; i < widget.dotCount; i++) {
- _animations.add(CurvedAnimation(parent: _controller, curve: Interval(i * dif, singleRollingDuration + i * dif, curve: widget.loadingCurve)));
- }
+ _generateDotAnimations();
+ _setDotCurves();
+
+ setLoadingState(widget.loading ? LoadingState.LOADING : LoadingState.LOADED,
+ rebuild: false);
+ if (loading)
+ _controller.forward();
+ else
+ _appearingController.value = 1.0;
+ }
+
+ void _generateDotAnimations() {
+ _animations.forEach((a) => a.dispose());
+ _animations = List.generate(widget.dotCount,
+ (index) => CurvedAnimation(parent: _controller, curve: Curves.linear));
+ }
- _controller.forward();
+ void _setDotCurves() {
+ double dif = _animations.length <= 1
+ ? 0
+ : widget.rollingDuration *
+ (1 - widget.rollingFactor) /
+ (_animations.length - 1);
+ double singleRollingDuration =
+ widget.rollingDuration * widget.rollingFactor;
+ for (int i = 0; i < _animations.length; i++) {
+ _animations[i].curve = Interval(i * dif, singleRollingDuration + i * dif,
+ curve: widget.loadingCurve);
+ }
}
@override
@@ -183,86 +198,129 @@ class _CircularWidgetLoadingState extends State with Tick
super.dispose();
}
- Widget animatedSizeWidget(Key key) => Stack(
- children: [
- //Container(width: widget.minWidth, height: widget.minHeight,),
- Padding(
- padding: widget.padding,
- child: IgnorePointer(
- ignoring: !loaded,
- child: widget.animatedSize
- ? AnimatedSize(key: key, duration: widget.sizeDuration, vsync: this, curve: widget.sizeCurve, child: _child)
- : Container(key: key, child: _child)),
- ),
- ],
- );
+ Widget get _animatedSizeWidget {
+ final wrappedChild = WidgetWrapper(key: _childKey, child: _child);
+
+ return Padding(
+ padding: widget.padding,
+ child: IgnorePointer(
+ ignoring: !loaded,
+ child: widget.animatedSize
+ ? AnimatedSize(
+ key: _animatedSizeKey,
+ duration: widget.sizeDuration,
+ curve: widget.sizeCurve,
+ child: wrappedChild)
+ : wrappedChild),
+ );
+ }
@override
- Widget build(BuildContext context) {
+ void didUpdateWidget(covariant CircularWidgetLoading oldWidget) {
+ super.didUpdateWidget(oldWidget);
+
+ if (_animations.length != widget.dotCount) _generateDotAnimations();
+ if (_animations.length != widget.dotCount ||
+ oldWidget.rollingFactor != widget.rollingFactor ||
+ oldWidget.rollingDuration != widget.rollingFactor ||
+ oldWidget.loadingCurve != widget.loadingCurve) _setDotCurves();
+
+ _appearingController.duration = widget.appearingDuration;
+ _appearingAnimation.curve = widget.appearingCurve;
+ _controller.duration = widget.loadingDuration;
+
if ((loaded || appearing) && widget.loading) {
- loadingState = LoadingState.DISAPPEARING;
+ setLoadingState(LoadingState.DISAPPEARING, rebuild: false);
_appearingController.reverse();
} else if (disappearing && !widget.loading) {
- loadingState = LoadingState.APPEARING;
+ setLoadingState(LoadingState.APPEARING, rebuild: false);
_appearingController.forward();
}
+ }
+ @override
+ Widget build(BuildContext context) {
if (!disappearing) _child = widget.child;
-
- Widget loadedChild = animatedSizeWidget(_childKey);
ThemeData theme = Theme.of(context);
- Color dotColor = widget.dotColor ?? theme.accentColor;
- TextDirection textDirection = Directionality.maybeOf(context) ?? TextDirection.ltr;
+ Widget loadedChild = _animatedSizeWidget;
+ Color dotColor = widget.dotColor ?? theme.colorScheme.secondary;
+ TextDirection textDirection =
+ Directionality.maybeOf(context) ?? TextDirection.ltr;
Widget stack = Stack(
children: [
- if (loading)
+ if (loading) ...[
WidgetSizedBox(
child: loadedChild,
),
- if (loaded)
- loadedChild
- else if (appearing || disappearing)
- ClipOval(
- clipper: _DotClipper(_appearingAnimation.value, widget.dotRadius, widget.maxLoadingCircleSize, widget.loadingCirclePadding),
- child: Stack(children: [
- Container(
- foregroundDecoration: BoxDecoration(color: dotColor.withOpacity(dotColor.opacity * (1 - _appearingAnimation.value))), child: loadedChild)
- ]),
- )
- else
Positioned.fill(
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
- double radius =
- min(widget.maxLoadingCircleSize, min(constraints.maxWidth, constraints.maxHeight) - 2 * widget.loadingCirclePadding) / 2 - widget.dotRadius;
+ double radius = min(
+ widget.maxLoadingCircleSize,
+ min(constraints.maxWidth, constraints.maxHeight) -
+ 2 * widget.loadingCirclePadding) /
+ 2 -
+ widget.dotRadius;
double x = constraints.maxWidth / 2;
double y = constraints.maxHeight / 2;
return Stack(
- children: List.generate(_animations.length, (index) => index).map((i) {
+ children:
+ List.generate(_animations.length, (index) => index)
+ .map((i) {
Animation animation = _animations[i];
- double radian = 0.5 * pi - 2 * pi * animation.value;
- double dotRadius = widget.dotRadius * (widget.minDotRadiusFactor + (1 - widget.minDotRadiusFactor) * (1 - i / _animations.length));
- return Positioned(
- child: widget.dotBuilder?.call(widget.dotRadius) ?? loadingPoint(dotRadius),
- top: y - radius * sin(radian) - dotRadius,
- left: x - radius * cos(radian) - dotRadius,
- );
+ double dotRadius = widget.dotRadius *
+ (widget.minDotRadiusFactor +
+ (1 - widget.minDotRadiusFactor) *
+ (1 - i / _animations.length));
+ return AnimatedBuilder(
+ animation: animation,
+ child: widget.dotBuilder?.call(widget.dotRadius) ??
+ loadingPoint(dotRadius, dotColor),
+ builder: (context, child) {
+ double radian = 0.5 * pi - 2 * pi * animation.value;
+ return Positioned(
+ child: child!,
+ top: y - radius * sin(radian) - dotRadius,
+ left: x - radius * cos(radian) - dotRadius,
+ );
+ });
}).toList());
},
),
),
+ ] else if (loaded)
+ loadedChild
+ else
+ AnimatedBuilder(
+ animation: _appearingAnimation,
+ builder: (context, child) => ClipOval(
+ clipper: _DotClipper(_appearingAnimation.value, widget.dotRadius,
+ widget.maxLoadingCircleSize, widget.loadingCirclePadding),
+ child: Stack(children: [
+ DecoratedBox(
+ position: DecorationPosition.foreground,
+ decoration: BoxDecoration(
+ color: dotColor.withOpacity(dotColor.opacity *
+ (1 - _appearingAnimation.value))),
+ child: loadedChild)
+ ]),
+ ),
+ )
],
);
return Directionality(textDirection: textDirection, child: stack);
}
- Widget loadingPoint(double radius) {
+ Widget loadingPoint(double radius, Color color) {
return Container(
width: radius * 2,
height: radius * 2,
- decoration: BoxDecoration(color: widget.dotColor ?? Theme.of(context).accentColor, borderRadius: BorderRadius.all(Radius.circular(radius))),
+ decoration: BoxDecoration(
+ color: color,
+ borderRadius: BorderRadius.all(Radius.circular(radius)),
+ ),
);
}
}
@@ -273,17 +331,23 @@ class _DotClipper extends CustomClipper {
final double maxLoadingCircleSize;
final double loadingCirclePadding;
- _DotClipper(this.factor, this.dotRadius, this.maxLoadingCircleSize, this.loadingCirclePadding);
+ _DotClipper(this.factor, this.dotRadius, this.maxLoadingCircleSize,
+ this.loadingCirclePadding);
@override
Rect getClip(Size size) {
- double radius = min(maxLoadingCircleSize, min(size.width, size.height) - 2 * loadingCirclePadding) / 2 - dotRadius;
+ double radius = min(maxLoadingCircleSize,
+ min(size.width, size.height) - 2 * loadingCirclePadding) /
+ 2 -
+ dotRadius;
double x = size.width / 2;
double y = size.height / 2;
double maxAppearingRadius = sqrt(x * x + y * y);
- double appearingRadius = dotRadius + factor * (maxAppearingRadius - dotRadius);
- return Rect.fromCircle(center: Offset(x, y - radius), radius: appearingRadius);
+ double appearingRadius =
+ dotRadius + factor * (maxAppearingRadius - dotRadius);
+ return Rect.fromCircle(
+ center: Offset(x, y - radius), radius: appearingRadius);
}
@override
diff --git a/lib/src/widgets/loading_widget.dart b/lib/src/widgets/loading_widget.dart
index 70f4060..1186c69 100644
--- a/lib/src/widgets/loading_widget.dart
+++ b/lib/src/widgets/loading_widget.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:widget_loading/src/utils/loading_state.dart';
+// unused because of problems with documentation of constructor parameters
abstract class LoadingWidget extends StatefulWidget {
final Widget child;
@@ -46,13 +47,20 @@ abstract class LoadingWidget extends StatefulWidget {
: super(key: key);
}
-abstract class LoadingWidgetState {
+abstract class LoadingWidgetState extends State {
LoadingState _loadingState = LoadingState.LOADED;
set loadingState(LoadingState value) {
+ setLoadingState(value);
+ }
+
+ void setLoadingState(LoadingState value, {bool rebuild = true}) {
_loadingState = value;
+ if (rebuild && mounted) setState(() {});
}
+ LoadingState get loadingState => _loadingState;
+
bool get disappearing => _loadingState == LoadingState.DISAPPEARING;
bool get appearing => _loadingState == LoadingState.APPEARING;
diff --git a/lib/src/widgets/widget_sized_box.dart b/lib/src/widgets/widget_wrapper.dart
similarity index 58%
rename from lib/src/widgets/widget_sized_box.dart
rename to lib/src/widgets/widget_wrapper.dart
index dea9465..e451e24 100644
--- a/lib/src/widgets/widget_sized_box.dart
+++ b/lib/src/widgets/widget_wrapper.dart
@@ -13,3 +13,13 @@ class WidgetSizedBox extends StatelessWidget {
);
}
}
+
+class WidgetWrapper extends StatelessWidget {
+ final Widget child;
+ const WidgetWrapper({Key? key, required this.child}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return child;
+ }
+}
diff --git a/lib/src/widgets/wiper_loading.dart b/lib/src/widgets/wiper_loading.dart
index 3067eea..0f582c5 100644
--- a/lib/src/widgets/wiper_loading.dart
+++ b/lib/src/widgets/wiper_loading.dart
@@ -1,11 +1,10 @@
import 'dart:async';
import 'dart:math';
-import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:widget_loading/src/utils/extensions.dart';
import 'package:widget_loading/src/utils/loading_state.dart';
-import 'package:widget_loading/src/widgets/widget_sized_box.dart';
+import 'package:widget_loading/src/widgets/widget_wrapper.dart';
import 'loading_widget.dart';
@@ -121,9 +120,11 @@ class WiperLoading extends StatefulWidget {
_WiperLoadingState createState() => _WiperLoadingState();
}
-class _WiperLoadingState extends State with TickerProviderStateMixin, LoadingWidgetState {
+class _WiperLoadingState extends LoadingWidgetState
+ with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final CurvedAnimation _animation;
+ final _animatedSizeKey = GlobalKey();
double _pointPosition = 0;
late Widget _child;
@@ -135,7 +136,8 @@ class _WiperLoadingState extends State with TickerProviderStateMix
_child = widget.child;
- loadingState = widget.loading ? LoadingState.LOADING : LoadingState.LOADED;
+ setLoadingState(widget.loading ? LoadingState.LOADING : LoadingState.LOADED,
+ rebuild: false);
_controller = AnimationController(
duration: widget.interval,
@@ -176,6 +178,8 @@ class _WiperLoadingState extends State with TickerProviderStateMix
break;
}
});
+
+ if (loaded) _controller.value = 1.0;
}
@override
@@ -192,7 +196,8 @@ class _WiperLoadingState extends State with TickerProviderStateMix
margin: EdgeInsets.zero,
color: color,
elevation: 5.0,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(min(width, height))),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(min(width, height))),
child: Container(
width: width,
height: height,
@@ -201,20 +206,27 @@ class _WiperLoadingState extends State with TickerProviderStateMix
);
}
- Widget animatedSizeWidget(Key key) => Stack(
- children: [
- Container(
- width: widget.minWidth,
- height: widget.minHeight,
- ),
- IgnorePointer(
- ignoring: !loaded,
- child: widget.animatedSize
- ? AnimatedSize(key: key, duration: widget.sizeDuration, vsync: this, curve: widget.sizeCurve, child: _child)
- : Container(key: key, child: _child),
- ),
- ],
- );
+ Widget animatedSizeWidget(Key key) {
+ final wrappedChild = WidgetWrapper(key: _childKey, child: _child);
+ return Stack(
+ children: [
+ SizedBox(
+ width: widget.minWidth,
+ height: widget.minHeight,
+ ),
+ IgnorePointer(
+ ignoring: !loaded,
+ child: widget.animatedSize
+ ? AnimatedSize(
+ key: _animatedSizeKey,
+ duration: widget.sizeDuration,
+ curve: widget.sizeCurve,
+ child: wrappedChild)
+ : wrappedChild,
+ ),
+ ],
+ );
+ }
bool get up => widget.direction == WiperDirection.up;
@@ -225,55 +237,65 @@ class _WiperLoadingState extends State with TickerProviderStateMix
bool get left => widget.direction == WiperDirection.left;
@override
- Widget build(BuildContext context) {
+ void didUpdateWidget(covariant WiperLoading oldWidget) {
+ super.didUpdateWidget(oldWidget);
if (loaded && widget.loading) {
- loadingState = LoadingState.DISAPPEARING;
+ setLoadingState(LoadingState.DISAPPEARING, rebuild: false);
_controller.animateBack(0.0);
}
+ }
+ @override
+ Widget build(BuildContext context) {
if (!disappearing) _child = widget.child;
Widget _loadedChild = animatedSizeWidget(_childKey);
- Color color = widget.wiperColor ?? Theme.of(context).accentColor;
+ Color color = widget.wiperColor ?? Theme.of(context).colorScheme.secondary;
bool vertical = up || down;
- TextDirection textDirection = Directionality.maybeOf(context) ?? TextDirection.ltr;
+ TextDirection textDirection =
+ Directionality.maybeOf(context) ?? TextDirection.ltr;
Widget stack = Stack(
children: [
- //WidgetSizedBox(child: animatedSizeWidget(pseudoChildKey),),
- Container(
- width: widget.minWidth,
- height: widget.minHeight,
- ),
- if (!loaded)
+ if (loaded)
+ _loadedChild
+ else ...[
appearing || disappearing
- ? ClipRect(
- clipper: _WiperRectClipper(widget.direction, _animation.value),
- child: _loadedChild,
+ ? AnimatedBuilder(
+ animation: _animation,
+ builder: (context, child) => ClipRect(
+ clipper:
+ _WiperRectClipper(widget.direction, _animation.value),
+ child: _loadedChild,
+ ),
)
: WidgetSizedBox(
child: _loadedChild,
),
- loaded
- ? _loadedChild
- : Positioned.fill(
- child: LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- Size biggest = constraints.biggest;
- double height = constraints.hasBoundedHeight ? biggest.height : 50;
- double width = biggest.width;
- double _circleWidth =
- widget.wiperWidth * (1 + _animation.speed.abs() * widget.wiperDeformingFactor) * (appearing || disappearing ? 1 - _animation.value : 1);
- /*((appearing || disappearing)
- ? (_animation.value > 0.5
- ? (2 * (1 - _animation.value) + 9 * pow(1 - (_animation.value), 2))
- : (1.0 + 9 * pow(0.5 - (_animation.value - 0.5).abs(), 2)))
- : (loaded ? 0.0 : (1.0 + 9 * pow(0.5 - (_animation.value - 0.5).abs(), 2))));*/
- Widget wiper = widget.wiperBuilder?.call(vertical ? width : _circleWidth, vertical ? _circleWidth : height) ??
- _loadingWiper(vertical ? width : _circleWidth, vertical ? _circleWidth : height, color);
- _pointPosition = (_animation.value * ((vertical ? height : width) - _circleWidth));
- return Container(
+ Positioned.fill(
+ child: LayoutBuilder(
+ builder: (BuildContext context, BoxConstraints constraints) {
+ Size biggest = constraints.biggest;
+ double height =
+ constraints.hasBoundedHeight ? biggest.height : 50;
+ double width = biggest.width;
+ return AnimatedBuilder(
+ animation: _animation,
+ builder: (context, child) {
+ double _circleWidth = widget.wiperWidth *
+ (1 +
+ _animation.speed.abs() *
+ widget.wiperDeformingFactor) *
+ (appearing || disappearing ? 1 - _animation.value : 1);
+ Widget wiper = widget.wiperBuilder?.call(
+ vertical ? width : _circleWidth,
+ vertical ? _circleWidth : height) ??
+ _loadingWiper(vertical ? width : _circleWidth,
+ vertical ? _circleWidth : height, color);
+ _pointPosition = (_animation.value *
+ ((vertical ? height : width) - _circleWidth));
+ return SizedBox(
width: width,
height: height,
child: Stack(
@@ -289,8 +311,11 @@ class _WiperLoadingState extends State with TickerProviderStateMix
),
);
},
- ),
- ),
+ );
+ },
+ ),
+ ),
+ ],
],
);
return Directionality(textDirection: textDirection, child: stack);
@@ -306,11 +331,13 @@ class _WiperRectClipper extends CustomClipper {
@override
Rect getClip(Size size) {
return direction == WiperDirection.left
- ? Rect.fromLTWH(size.width * (1 - factor), 0, size.width * factor, size.height)
+ ? Rect.fromLTWH(
+ size.width * (1 - factor), 0, size.width * factor, size.height)
: direction == WiperDirection.right
? Rect.fromLTWH(0, 0, size.width * factor, size.height)
: direction == WiperDirection.up
- ? Rect.fromLTWH(0, size.height * (1 - factor), size.width, size.height * factor)
+ ? Rect.fromLTWH(0, size.height * (1 - factor), size.width,
+ size.height * factor)
: Rect.fromLTWH(0, 0, size.width, size.height * factor);
}
@@ -321,7 +348,11 @@ class _WiperRectClipper extends CustomClipper {
@override
bool operator ==(Object other) =>
- identical(this, other) || other is _WiperRectClipper && runtimeType == other.runtimeType && direction == other.direction && factor == other.factor;
+ identical(this, other) ||
+ other is _WiperRectClipper &&
+ runtimeType == other.runtimeType &&
+ direction == other.direction &&
+ factor == other.factor;
@override
int get hashCode => direction.hashCode ^ factor.hashCode;
diff --git a/pubspec.lock b/pubspec.lock
index b55f540..1df6b69 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -7,7 +7,7 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.5.0"
+ version: "2.8.2"
boolean_selector:
dependency: transitive
description:
@@ -21,14 +21,14 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0"
+ version: "1.3.1"
clock:
dependency: transitive
description:
@@ -66,14 +66,21 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.10"
+ version: "0.12.11"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.3"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.3.0"
+ version: "1.7.0"
path:
dependency: transitive
description:
@@ -92,7 +99,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
- version: "1.8.0"
+ version: "1.8.1"
stack_trace:
dependency: transitive
description:
@@ -127,7 +134,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.19"
+ version: "0.4.8"
typed_data:
dependency: transitive
description:
@@ -141,7 +148,7 @@ packages:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
sdks:
- dart: ">=2.12.0 <3.0.0"
+ dart: ">=2.14.0 <3.0.0"
flutter: ">=1.17.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 50590fa..c9b70ab 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: widget_loading
description: An easy way to hide a widget when you have nothing to show yet and need a loading animation at the same time.
-version: 0.2.1
+version: 0.3.0
repository: https://github.com/SplashByte/widget_loading
environment:
diff --git a/test/widget_loading_test.dart b/test/widget_loading_test.dart
index 1a13b85..c1574ad 100644
--- a/test/widget_loading_test.dart
+++ b/test/widget_loading_test.dart
@@ -4,4 +4,4 @@
void main() {
//test('', () {});
-}
\ No newline at end of file
+}