Skip to content

Commit aa5d7b6

Browse files
authored
Newly constructed tweens should have same begin and end (#94363)
1 parent 7b8df6e commit aa5d7b6

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

packages/flutter/lib/src/widgets/implicit_animations.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
429429
tween ??= constructor(targetValue);
430430
if (_shouldAnimateTween(tween, targetValue))
431431
shouldStartAnimation = true;
432+
else
433+
tween.end ??= tween.begin;
432434
} else {
433435
tween = null;
434436
}

packages/flutter/test/widgets/implicit_animations_test.dart

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ void main() {
8585
expect(mockOnEndFunction.called, 0);
8686
await tester.pump(additionalDelay);
8787
expect(mockOnEndFunction.called, 1);
88+
89+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
8890
});
8991

9092
testWidgets('AnimatedPadding onEnd callback test', (WidgetTester tester) async {
@@ -106,6 +108,8 @@ void main() {
106108
expect(mockOnEndFunction.called, 0);
107109
await tester.pump(additionalDelay);
108110
expect(mockOnEndFunction.called, 1);
111+
112+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
109113
});
110114

111115
testWidgets('AnimatedAlign onEnd callback test', (WidgetTester tester) async {
@@ -127,6 +131,8 @@ void main() {
127131
expect(mockOnEndFunction.called, 0);
128132
await tester.pump(additionalDelay);
129133
expect(mockOnEndFunction.called, 1);
134+
135+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
130136
});
131137

132138
testWidgets('AnimatedPositioned onEnd callback test', (WidgetTester tester) async {
@@ -148,6 +154,8 @@ void main() {
148154
expect(mockOnEndFunction.called, 0);
149155
await tester.pump(additionalDelay);
150156
expect(mockOnEndFunction.called, 1);
157+
158+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
151159
});
152160

153161
testWidgets('AnimatedPositionedDirectional onEnd callback test', (WidgetTester tester) async {
@@ -169,6 +177,8 @@ void main() {
169177
expect(mockOnEndFunction.called, 0);
170178
await tester.pump(additionalDelay);
171179
expect(mockOnEndFunction.called, 1);
180+
181+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
172182
});
173183

174184
testWidgets('AnimatedSlide onEnd callback test', (WidgetTester tester) async {
@@ -189,6 +199,8 @@ void main() {
189199
expect(mockOnEndFunction.called, 0);
190200
await tester.pump(additionalDelay);
191201
expect(mockOnEndFunction.called, 1);
202+
203+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
192204
});
193205

194206
testWidgets('AnimatedSlide transition test', (WidgetTester tester) async {
@@ -247,6 +259,8 @@ void main() {
247259
expect(mockOnEndFunction.called, 0);
248260
await tester.pump(additionalDelay);
249261
expect(mockOnEndFunction.called, 1);
262+
263+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
250264
});
251265

252266
testWidgets('AnimatedScale transition test', (WidgetTester tester) async {
@@ -305,6 +319,8 @@ void main() {
305319
expect(mockOnEndFunction.called, 0);
306320
await tester.pump(additionalDelay);
307321
expect(mockOnEndFunction.called, 1);
322+
323+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
308324
});
309325

310326
testWidgets('AnimatedRotation transition test', (WidgetTester tester) async {
@@ -363,6 +379,8 @@ void main() {
363379
expect(mockOnEndFunction.called, 0);
364380
await tester.pump(additionalDelay);
365381
expect(mockOnEndFunction.called, 1);
382+
383+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
366384
});
367385

368386
testWidgets('AnimatedOpacity transition test', (WidgetTester tester) async {
@@ -421,6 +439,8 @@ void main() {
421439
expect(mockOnEndFunction.called, 0);
422440
await tester.pump(additionalDelay);
423441
expect(mockOnEndFunction.called, 1);
442+
443+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
424444
});
425445

426446
testWidgets('SliverAnimatedOpacity transition test', (WidgetTester tester) async {
@@ -480,6 +500,8 @@ void main() {
480500
expect(mockOnEndFunction.called, 0);
481501
await tester.pump(additionalDelay);
482502
expect(mockOnEndFunction.called, 1);
503+
504+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
483505
});
484506

485507
testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
@@ -501,6 +523,8 @@ void main() {
501523
expect(mockOnEndFunction.called, 0);
502524
await tester.pump(additionalDelay);
503525
expect(mockOnEndFunction.called, 1);
526+
527+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
504528
});
505529

506530
testWidgets('TweenAnimationBuilder onEnd callback test', (WidgetTester tester) async {
@@ -522,6 +546,8 @@ void main() {
522546
expect(mockOnEndFunction.called, 0);
523547
await tester.pump(additionalDelay);
524548
expect(mockOnEndFunction.called, 1);
549+
550+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
525551
});
526552

527553
testWidgets('AnimatedTheme onEnd callback test', (WidgetTester tester) async {
@@ -543,6 +569,8 @@ void main() {
543569
expect(mockOnEndFunction.called, 0);
544570
await tester.pump(additionalDelay);
545571
expect(mockOnEndFunction.called, 1);
572+
573+
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
546574
});
547575

548576
testWidgets('Ensure CurvedAnimations are disposed on widget change',
@@ -599,6 +627,21 @@ void main() {
599627
});
600628
}
601629

630+
Future<void> tapTest2and3(WidgetTester tester, Finder widgetFinder,
631+
MockOnEndFunction mockOnEndFunction) async {
632+
await tester.tap(widgetFinder);
633+
634+
await tester.pump();
635+
await tester.pump(animationDuration + additionalDelay);
636+
expect(mockOnEndFunction.called, 2);
637+
638+
await tester.tap(widgetFinder);
639+
640+
await tester.pump();
641+
await tester.pump(animationDuration + additionalDelay);
642+
expect(mockOnEndFunction.called, 3);
643+
}
644+
602645
Widget wrap({required Widget child}) {
603646
return Directionality(
604647
textDirection: TextDirection.ltr,
@@ -664,6 +707,7 @@ class _TestAnimatedContainerWidgetState extends _TestAnimatedWidgetState {
664707
duration: duration,
665708
onEnd: widget.callback,
666709
width: toggle ? 10 : 20,
710+
foregroundDecoration: toggle ? const BoxDecoration() : null,
667711
child: child,
668712
);
669713
}
@@ -835,7 +879,7 @@ class _TestTweenAnimationBuilderWidgetState extends _TestAnimatedWidgetState {
835879
@override
836880
Widget getAnimatedWidget() {
837881
return TweenAnimationBuilder<double>(
838-
tween: Tween<double>(begin: 1, end: 2),
882+
tween: toggle ? Tween<double>(begin: 1, end: 2) : Tween<double>(begin: 2, end: 1),
839883
duration: duration,
840884
onEnd: widget.callback,
841885
child: child,

0 commit comments

Comments
 (0)