Skip to content

Commit d2a5496

Browse files
authored
Fix misc bugs (#709)
* Fix animation bug when switching themes * Fix missing FlagProperty constructor parameter in FSidebar * Prepare Forui for review * Upgrade to Gradle 9 --------- Co-authored-by: Pante <[email protected]>
1 parent de4eaa5 commit d2a5496

File tree

11 files changed

+105
-74
lines changed

11 files changed

+105
-74
lines changed

forui/example/android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ if (flutterVersionName == null) {
2323
}
2424

2525
android {
26-
namespace "com.foruslabs.forui.samples.samples"
27-
compileSdk 35
26+
namespace "com.foruslabs.forui.example"
27+
compileSdk 36
2828

2929
compileOptions {
3030
sourceCompatibility JavaVersion.VERSION_17

forui/example/android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
zipStoreBase=GRADLE_USER_HOME
44
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip

forui/lib/src/foundation/tappable.dart

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ class AnimatedTappableState extends _FTappableState<AnimatedTappable> with Singl
422422
Animation<double>? bounce;
423423

424424
FTappableStyle? _style;
425-
AnimationController? _bounceController;
426-
CurvedAnimation? _curvedBounce;
425+
late final AnimationController _bounceController = AnimationController(vsync: this);
426+
late final CurvedAnimation _curvedBounce = CurvedAnimation(parent: _bounceController, curve: Curves.linear);
427427

428428
@override
429429
void didChangeDependencies() {
@@ -441,27 +441,20 @@ class AnimatedTappableState extends _FTappableState<AnimatedTappable> with Singl
441441
final style = widget.style?.call(context.theme.tappableStyle) ?? context.theme.tappableStyle;
442442
if (_style != style) {
443443
_style = style;
444-
_curvedBounce?.dispose();
445-
_bounceController?.dispose();
446-
447-
_bounceController = AnimationController(
448-
vsync: this,
449-
duration: style.motion.bounceDownDuration,
450-
reverseDuration: style.motion.bounceUpDuration,
451-
);
452-
_curvedBounce = CurvedAnimation(
453-
parent: _bounceController!,
454-
curve: style.motion.bounceDownCurve,
455-
reverseCurve: style.motion.bounceUpCurve,
456-
);
457-
bounce = style.motion.bounceTween.animate(_curvedBounce!);
444+
_bounceController
445+
..duration = style.motion.bounceDownDuration
446+
..reverseDuration = style.motion.bounceUpDuration;
447+
_curvedBounce
448+
..curve = style.motion.bounceDownCurve
449+
..reverseCurve = style.motion.bounceUpCurve;
450+
bounce = style.motion.bounceTween.animate(_curvedBounce);
458451
}
459452
}
460453

461454
@override
462455
void dispose() {
463-
_curvedBounce?.dispose();
464-
_bounceController?.dispose();
456+
_curvedBounce.dispose();
457+
_bounceController.dispose();
465458
super.dispose();
466459
}
467460

@@ -478,15 +471,15 @@ class AnimatedTappableState extends _FTappableState<AnimatedTappable> with Singl
478471
void onPressedStart() {
479472
// Check if it's mounted due to a non-deterministic race condition, https://github.com/forus-labs/forui/issues/482.
480473
if (mounted) {
481-
_bounceController?.forward();
474+
_bounceController.forward();
482475
}
483476
}
484477

485478
@override
486479
void onPressedEnd() {
487480
// Check if it's mounted due to a non-deterministic race condition, https://github.com/forus-labs/forui/issues/482.
488481
if (mounted) {
489-
_bounceController?.reverse();
482+
_bounceController.reverse();
490483
}
491484
}
492485

forui/lib/src/widgets/progresses/circular_progress.dart

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class FCircularProgress extends StatefulWidget {
4949

5050
class _CircularState extends State<FCircularProgress> with SingleTickerProviderStateMixin {
5151
FCircularProgressStyle? _style;
52-
AnimationController? _controller;
53-
CurvedAnimation? _curveRotation;
54-
Animation<double>? _rotation;
52+
late final AnimationController _controller = AnimationController(vsync: this);
53+
late final CurvedAnimation _curveRotation = CurvedAnimation(parent: _controller, curve: Curves.linear);
54+
late Animation<double> _rotation;
5555

5656
@override
5757
void didChangeDependencies() {
@@ -70,19 +70,18 @@ class _CircularState extends State<FCircularProgress> with SingleTickerProviderS
7070
final style = widget.style?.call(inherited) ?? inherited;
7171
if (_style != style) {
7272
_style = style;
73-
_curveRotation?.dispose();
74-
_controller?.dispose();
75-
76-
_controller = AnimationController(vsync: this, duration: style.motion.duration)..repeat();
77-
_curveRotation = CurvedAnimation(parent: _controller!, curve: style.motion.curve);
78-
_rotation = style.motion.tween.animate(_curveRotation!);
73+
_controller
74+
..duration = style.motion.duration
75+
..repeat();
76+
_curveRotation.curve = style.motion.curve;
77+
_rotation = style.motion.tween.animate(_curveRotation);
7978
}
8079
}
8180

8281
@override
8382
void dispose() {
84-
_curveRotation?.dispose();
85-
_controller?.dispose();
83+
_curveRotation.dispose();
84+
_controller.dispose();
8685
super.dispose();
8786
}
8887

@@ -91,8 +90,8 @@ class _CircularState extends State<FCircularProgress> with SingleTickerProviderS
9190
final semanticsLabel =
9291
widget.semanticsLabel ?? (FLocalizations.of(context) ?? FDefaultLocalizations()).progressSemanticsLabel;
9392
return AnimatedBuilder(
94-
animation: _rotation!,
95-
builder: (_, child) => Transform.rotate(angle: _rotation!.value * 2 * math.pi, child: child),
93+
animation: _rotation,
94+
builder: (_, child) => Transform.rotate(angle: _rotation.value * 2 * math.pi, child: child),
9695
child: IconTheme(
9796
data: _style!.iconStyle,
9897
child: Icon(widget.icon, semanticLabel: semanticsLabel),

forui/lib/src/widgets/progresses/determinate_progress.dart

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class FDeterminateProgress extends StatefulWidget {
4646

4747
class _State extends State<FDeterminateProgress> with SingleTickerProviderStateMixin {
4848
FDeterminateProgressStyle? _style;
49-
AnimationController? _controller;
50-
CurvedAnimation? _animation;
49+
late final AnimationController _controller = AnimationController(vsync: this);
50+
late final CurvedAnimation _animation = CurvedAnimation(parent: _controller, curve: Curves.linear);
5151

5252
@override
5353
void didChangeDependencies() {
@@ -63,27 +63,24 @@ class _State extends State<FDeterminateProgress> with SingleTickerProviderStateM
6363

6464
void _setup() {
6565
final style = widget.style?.call(context.theme.determinateProgressStyle) ?? context.theme.determinateProgressStyle;
66-
final previous = _controller?.value ?? 0.0;
6766

6867
if (_style != style) {
6968
_style = style;
70-
_animation?.dispose();
71-
_controller?.dispose();
72-
73-
_controller = AnimationController(vsync: this, value: previous, duration: style.motion.duration);
74-
_animation = CurvedAnimation(parent: _controller!, curve: style.motion.curve);
69+
_controller
70+
..value = _controller.value
71+
..duration = style.motion.duration;
72+
_animation.curve = style.motion.curve;
7573
}
7674

77-
if (widget.value != previous) {
78-
_controller!.value = previous;
79-
_controller!.animateTo(widget.value, duration: style.motion.duration * (widget.value - previous).abs());
75+
if (widget.value != _controller.value) {
76+
_controller.animateTo(widget.value, duration: style.motion.duration * (widget.value - _controller.value).abs());
8077
}
8178
}
8279

8380
@override
8481
void dispose() {
85-
_animation?.dispose();
86-
_controller?.dispose();
82+
_animation.dispose();
83+
_controller.dispose();
8784
super.dispose();
8885
}
8986

@@ -97,8 +94,8 @@ class _State extends State<FDeterminateProgress> with SingleTickerProviderStateM
9794
child: Align(
9895
alignment: AlignmentDirectional.centerStart,
9996
child: AnimatedBuilder(
100-
animation: _animation!,
101-
builder: (_, child) => FractionallySizedBox(widthFactor: _animation!.value, child: child!),
97+
animation: _animation,
98+
builder: (_, child) => FractionallySizedBox(widthFactor: _animation.value, child: child!),
10299
child: Container(decoration: _style!.fillDecoration),
103100
),
104101
),

forui/lib/src/widgets/progresses/progress.dart

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ class FProgress extends StatefulWidget {
4040

4141
class _ProgressState extends State<FProgress> with SingleTickerProviderStateMixin {
4242
FProgressStyle? _style;
43-
AnimationController? _controller;
44-
CurvedAnimation? _curved;
45-
Animation<double>? _animation;
43+
late final AnimationController _controller = AnimationController(vsync: this);
44+
late final CurvedAnimation _curved = CurvedAnimation(parent: _controller, curve: Curves.linear);
45+
late Animation<double> _animation;
4646

4747
@override
4848
void didChangeDependencies() {
@@ -60,25 +60,22 @@ class _ProgressState extends State<FProgress> with SingleTickerProviderStateMixi
6060
final style = widget.style?.call(context.theme.progressStyle) ?? context.theme.progressStyle;
6161
if (_style != style) {
6262
_style = style;
63-
_curved?.dispose();
64-
_controller?.dispose();
6563

6664
final total = style.motion.period + style.motion.interval;
67-
_controller = AnimationController(vsync: this, duration: total);
68-
_curved = CurvedAnimation(
69-
parent: _controller!,
70-
curve: Interval(0, style.motion.period.inMilliseconds / total.inMilliseconds, curve: style.motion.curve),
71-
);
72-
_animation = Tween<double>(begin: -style.motion.value, end: 1).animate(_curved!);
65+
final curve = Interval(0, style.motion.period.inMilliseconds / total.inMilliseconds, curve: style.motion.curve);
7366

74-
_controller!.repeat();
67+
_controller
68+
..duration = total
69+
..repeat();
70+
_curved.curve = curve;
71+
_animation = Tween<double>(begin: -style.motion.value, end: 1).animate(_curved);
7572
}
7673
}
7774

7875
@override
7976
void dispose() {
80-
_curved?.dispose();
81-
_controller?.dispose();
77+
_curved.dispose();
78+
_controller.dispose();
8279
super.dispose();
8380
}
8481

@@ -92,11 +89,11 @@ class _ProgressState extends State<FProgress> with SingleTickerProviderStateMixi
9289
decoration: _style!.trackDecoration,
9390
child: LayoutBuilder(
9491
builder: (context, constraints) => AnimatedBuilder(
95-
animation: _animation!,
92+
animation: _animation,
9693
builder: (_, child) => Stack(
9794
children: [
9895
PositionedDirectional(
99-
start: constraints.maxWidth * (_animation!.value),
96+
start: constraints.maxWidth * (_animation.value),
10097
width: constraints.maxWidth * _style!.motion.value,
10198
top: 0,
10299
bottom: 0,

forui/lib/src/widgets/sidebar/sidebar.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class FSidebar extends StatefulWidget {
131131
super.debugFillProperties(properties);
132132
properties
133133
..add(DiagnosticsProperty('style', style))
134-
..add(FlagProperty('autofocus', value: autofocus))
134+
..add(FlagProperty('autofocus', value: autofocus, ifTrue: 'autofocus'))
135135
..add(DiagnosticsProperty('focusNode', focusNode))
136136
..add(EnumProperty('traversalEdgeBehavior', traversalEdgeBehavior))
137137
..add(DoubleProperty('width', width));

forui/lib/src/widgets/toast/toaster_stack.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,9 @@ class _ToasterStackState extends State<ToasterStack> with SingleTickerProviderSt
7474
..duration = widget.style.motion.expandDuration
7575
..reverseDuration = widget.style.motion.collapseDuration
7676
..value = 0;
77-
_expand.dispose();
78-
_expand = CurvedAnimation(
79-
parent: _controller,
80-
curve: widget.style.motion.expandCurve,
81-
reverseCurve: widget.style.motion.collapseCurve,
82-
);
77+
_expand
78+
..curve = widget.style.motion.expandCurve
79+
..reverseCurve = widget.style.motion.collapseCurve;
8380
}
8481

8582
if (widget.style.expandBehavior != old.style.expandBehavior) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
3+
import 'package:forui/forui.dart';
4+
import '../../test_scaffold.dart';
5+
6+
void main() {
7+
testWidgets('ticker provider', (tester) async {
8+
await tester.pumpWidget(TestScaffold(theme: FThemes.zinc.light, child: const FCircularProgress()));
9+
await tester.pump();
10+
11+
await tester.pumpWidget(TestScaffold(theme: FThemes.zinc.dark, child: const FCircularProgress()));
12+
await tester.pump();
13+
14+
expect(tester.takeException(), null);
15+
});
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
3+
import 'package:forui/forui.dart';
4+
import '../../test_scaffold.dart';
5+
6+
void main() {
7+
testWidgets('ticker provider', (tester) async {
8+
await tester.pumpWidget(TestScaffold(theme: FThemes.zinc.light, child: const FDeterminateProgress(value: 0.5)));
9+
await tester.pump();
10+
11+
await tester.pumpWidget(TestScaffold(theme: FThemes.zinc.dark, child: const FDeterminateProgress(value: 0.6)));
12+
await tester.pump();
13+
14+
expect(tester.takeException(), null);
15+
});
16+
}

0 commit comments

Comments
 (0)