Jonny Borges

The easiest way of create animations with Flutter.

... ... @@ -3,6 +3,7 @@
/// injection, and route management in a quick and practical way.
library get;
export 'get_animations/index.dart';
export 'get_common/get_reset.dart';
export 'get_connect/connect.dart';
export 'get_core/get_core.dart';
... ...
import 'dart:math';
import 'package:flutter/widgets.dart';
import 'get_animated_builder.dart';
class FadeInAnimation extends OpacityAnimation {
FadeInAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
super.begin = 0,
super.end = 1,
super.idleValue = 0,
});
}
class FadeOutAnimation extends OpacityAnimation {
FadeOutAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
super.begin = 1,
super.end = 0,
super.idleValue = 1,
});
}
class OpacityAnimation extends GetAnimatedBuilder<double> {
OpacityAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
required super.onComplete,
required double begin,
required double end,
required super.idleValue,
}) : super(
tween: Tween<double>(begin: begin, end: end),
builder: (context, value, child) {
return Opacity(
opacity: value,
child: child!,
);
},
);
}
class RotateAnimation extends GetAnimatedBuilder<double> {
RotateAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
required double begin,
required double end,
super.idleValue = 0,
}) : super(
builder: (context, value, child) => Transform.rotate(
angle: value,
child: child,
),
tween: Tween<double>(begin: begin, end: end),
);
}
class ScaleAnimation extends GetAnimatedBuilder<double> {
ScaleAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
required double begin,
required double end,
super.idleValue = 0,
}) : super(
builder: (context, value, child) => Transform.scale(
scale: value,
child: child,
),
tween: Tween<double>(begin: begin, end: end),
);
}
class SlideAnimation extends GetAnimatedBuilder<Offset> {
SlideAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
required Offset begin,
required Offset end,
super.idleValue = const Offset(0, 0),
}) : super(
builder: (context, value, child) => Transform.translate(
offset: value,
child: child,
),
tween: Tween(begin: begin, end: end),
);
}
class BounceAnimation extends GetAnimatedBuilder<double> {
BounceAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
super.curve = Curves.bounceOut,
required double begin,
required double end,
super.idleValue = 0,
}) : super(
builder: (context, value, child) => Transform.scale(
scale: 1 + value.abs(),
child: child,
),
tween: Tween<double>(begin: begin, end: end),
);
}
class ShakeAnimation extends GetAnimatedBuilder<double> {
ShakeAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
required double begin,
required double end,
super.idleValue = 0,
}) : super(
builder: (context, value, child) => Transform.rotate(
angle: value * pi / 180.0,
child: child,
),
tween: Tween<double>(begin: begin, end: end),
);
}
class SpinAnimation extends GetAnimatedBuilder<double> {
SpinAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
super.idleValue = 0,
}) : super(
builder: (context, value, child) => Transform.rotate(
angle: value * pi / 180.0,
child: child,
),
tween: Tween<double>(begin: 0, end: 360),
);
}
class ColorAnimation extends GetAnimatedBuilder<Color?> {
ColorAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
required Color begin,
required Color end,
Color? idleColor,
}) : super(
builder: (context, value, child) => ColorFiltered(
colorFilter: ColorFilter.mode(
Color.lerp(begin, end, value!.value.toDouble())!,
BlendMode.srcIn,
),
child: child,
),
idleValue: idleColor ?? begin,
tween: ColorTween(begin: begin, end: end),
);
}
class SizeAnimation extends GetAnimatedBuilder<double> {
SizeAnimation({
super.key,
required super.duration,
required super.delay,
required super.child,
super.onComplete,
super.idleValue = 0,
required double begin,
required double end,
}) : super(
builder: (context, value, child) => Transform.scale(
scale: value,
child: child,
),
tween: Tween<double>(begin: begin, end: end),
);
}
... ...
import 'package:flutter/material.dart';
import 'animations.dart';
import 'get_animated_builder.dart';
const _defaultDuration = Duration(seconds: 2);
const _defaultDelay = Duration.zero;
extension AnimationExtension on Widget {
GetAnimatedBuilder? get _currentAnimation =>
(this is GetAnimatedBuilder) ? this as GetAnimatedBuilder : null;
GetAnimatedBuilder fadeIn({
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
assert(isSequential || this is! FadeOutAnimation,
'Can not use fadeOut + fadeIn when isSequential is false');
return FadeInAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder fadeOut({
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
assert(isSequential || this is! FadeInAnimation,
'Can not use fadeOut() + fadeIn when isSequential is false');
return FadeOutAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder rotate({
required double begin,
required double end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return RotateAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder scale({
required double begin,
required double end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return ScaleAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder slide({
required Offset begin,
required Offset end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return SlideAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder bounce({
required double begin,
required double end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return BounceAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder shake({
required double begin,
required double end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return ShakeAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder spin({
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return SpinAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
onComplete: onComplete,
child: this,
);
}
GetAnimatedBuilder size({
required double begin,
required double end,
Duration duration = _defaultDuration,
Duration delay = _defaultDelay,
ValueSetter<AnimationController>? onComplete,
bool isSequential = false,
}) {
return SizeAnimation(
duration: duration,
delay: _getDelay(isSequential, delay),
begin: begin,
end: end,
onComplete: onComplete,
child: this,
);
}
Duration _getDelay(bool isSequential, Duration delay) {
assert(!(isSequential && delay != Duration.zero),
"Error: When isSequential is true, delay must be non-zero. Context: isSequential: $isSequential delay: $delay");
return isSequential
? (_currentAnimation?.totalDuration ?? Duration.zero)
: delay;
}
}
... ...
import 'package:flutter/material.dart';
import 'animations.dart';
class GetAnimatedBuilder<T> extends StatefulWidget {
final Duration duration;
final Duration delay;
final Widget child;
final ValueSetter<AnimationController>? onComplete;
final ValueSetter<AnimationController>? onStart;
final Tween<T> tween;
final T idleValue;
final ValueWidgetBuilder<T> builder;
final Curve curve;
Duration get totalDuration => duration + delay;
const GetAnimatedBuilder({
super.key,
this.curve = Curves.linear,
this.onComplete,
this.onStart,
required this.duration,
required this.tween,
required this.idleValue,
required this.builder,
required this.child,
required this.delay,
});
@override
GetAnimatedBuilderState<T> createState() => GetAnimatedBuilderState<T>();
}
class GetAnimatedBuilderState<T> extends State<GetAnimatedBuilder<T>>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<T> _animation;
// AnimationController get controller => _controller;
// Animation<T> get animation => _animation;
bool _wasStarted = false;
// bool get wasStarted => _wasStarted;
late T _idleValue;
bool _willResetOnDispose = false;
bool get willResetOnDispose => _willResetOnDispose;
void _listener(AnimationStatus status) {
switch (status) {
case AnimationStatus.completed:
widget.onComplete?.call(_controller);
if (_willResetOnDispose) {
_controller.reset();
}
break;
// case AnimationStatus.dismissed:
case AnimationStatus.forward:
widget.onStart?.call(_controller);
break;
// case AnimationStatus.reverse:
default:
break;
}
}
@override
void initState() {
super.initState();
if (widget is OpacityAnimation) {
final current =
context.findRootAncestorStateOfType<GetAnimatedBuilderState>();
final isLast = current == null;
if (widget is FadeInAnimation) {
_idleValue = 1.0 as dynamic;
} else {
if (isLast) {
_willResetOnDispose = false;
} else {
_willResetOnDispose = true;
}
_idleValue = widget.idleValue;
}
} else {
_idleValue = widget.idleValue;
}
_controller = AnimationController(
vsync: this,
duration: widget.duration,
);
_controller.addStatusListener(_listener);
_animation = widget.tween.animate(
CurvedAnimation(
parent: _controller,
curve: widget.curve,
),
);
Future.delayed(widget.delay, () {
if (mounted) {
setState(() {
_wasStarted = true;
_controller.forward();
});
}
});
}
@override
void dispose() {
_controller.removeStatusListener(_listener);
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
final value = _wasStarted ? _animation.value : _idleValue;
return widget.builder(context, value, child);
},
child: widget.child,
);
}
}
... ...
export './animations.dart';
export './extensions.dart';
export './get_animated_builder.dart';
... ...
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
void main() {
group('Animation Extension', () {
Widget buildWidget() {
return Container(
width: 100,
height: 100,
color: Colors.red,
);
}
testWidgets('fadeIn() and fadeOut() can not be used sequentially',
(WidgetTester tester) async {
final widget = buildWidget();
expect(() => widget.fadeIn().fadeOut(), throwsAssertionError);
expect(() => widget.fadeOut().fadeIn(), throwsAssertionError);
expect(() => widget.fadeIn(isSequential: true).fadeOut(),
throwsAssertionError);
expect(() => widget.fadeOut(isSequential: true).fadeIn(),
throwsAssertionError);
});
testWidgets('can not use delay when isSequential is true',
(WidgetTester tester) async {
final widget = buildWidget();
expect(
() => widget.fadeIn(
isSequential: true, delay: const Duration(seconds: 1)),
throwsAssertionError);
});
testWidgets(
'fadeIn() and fadeOut() can be used together when isSequential is true',
(WidgetTester tester) async {
final widget = buildWidget();
expect(
() => widget.fadeIn(isSequential: true).fadeOut(isSequential: true),
isNot(throwsException));
expect(() => widget.fadeIn().fadeOut(isSequential: true),
isNot(throwsException));
});
testWidgets('fadeIn() returns a FadeInAnimation',
(WidgetTester tester) async {
final widget = buildWidget();
const begin = 0.0;
const end = 1.0;
final animation = widget.fadeIn();
expect(animation, isA<FadeInAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('fadeOut() returns a animation', (WidgetTester tester) async {
final widget = buildWidget();
const begin = 1.0;
const end = 0.0;
final animation = widget.fadeOut();
expect(animation, isA<FadeOutAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('rotate() returns a RotateAnimation',
(WidgetTester tester) async {
const begin = 0.9;
const end = 1.1;
final widget = buildWidget();
final animation = widget.rotate(begin: begin, end: end);
expect(animation, isA<RotateAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('scale() returns a ScaleAnimation',
(WidgetTester tester) async {
const begin = 0.9;
const end = 1.1;
final widget = buildWidget();
final animation = widget.scale(begin: begin, end: end);
expect(animation, isA<ScaleAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('slide() returns a SlideAnimation',
(WidgetTester tester) async {
const begin = Offset.zero;
const end = Offset.zero;
final widget = buildWidget();
final animation = widget.slide(begin: begin, end: end);
expect(animation, isA<SlideAnimation>());
_testDefaultValues<Offset>(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('bounce() returns a BounceAnimation',
(WidgetTester tester) async {
const begin = 0.9;
const end = 1.1;
final widget = buildWidget();
final animation = widget.bounce(begin: begin, end: end);
expect(animation, isA<BounceAnimation>());
_testDefaultValues(
animation: animation,
widget: widget,
begin: begin,
end: end,
curve: Curves.bounceOut,
);
});
testWidgets('shake() returns a ShakeAnimation',
(WidgetTester tester) async {
const begin = 0.9;
const end = 1.1;
final widget = buildWidget();
final animation = widget.shake(begin: begin, end: end);
expect(animation, isA<ShakeAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('spin() returns a SpinAnimation', (WidgetTester tester) async {
final widget = buildWidget();
const begin = 0.0;
const end = 360;
final animation = widget.spin();
expect(animation, isA<SpinAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
testWidgets('size() returns a SizeAnimation', (WidgetTester tester) async {
final widget = buildWidget();
const begin = 0.9;
const end = 1.1;
final animation = widget.size(begin: begin, end: end);
expect(animation, isA<SizeAnimation>());
_testDefaultValues(
animation: animation, widget: widget, begin: begin, end: end);
});
});
}
void _testDefaultValues<T>({
required GetAnimatedBuilder animation,
required Widget widget,
required T begin,
required T end,
Curve curve = Curves.linear,
}) {
expect(animation.tween.begin, begin);
expect(animation.tween.end, end);
if (animation.idleValue is Offset) {
expect(animation.idleValue, Offset.zero);
} else if (animation is FadeOutAnimation) {
expect(animation.idleValue, 1);
} else {
expect(animation.idleValue, 0);
}
expect(animation.delay, Duration.zero);
expect(animation.child, widget);
expect(animation.curve, curve);
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
class _Wrapper extends StatelessWidget {
const _Wrapper({required this.child});
final Widget child;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: child),
);
}
}
void main() {
testWidgets('GetAnimatedBuilder defaults', (WidgetTester tester) async {
await tester.pumpWidget(
_Wrapper(
child: GetAnimatedBuilder<int>(
duration: const Duration(milliseconds: 500),
tween: Tween(begin: 0, end: 10),
idleValue: 0,
builder: (_, value, __) => Text(value.toString()),
delay: Duration.zero,
child: Container(),
),
),
);
// Verify that the widget starts with the idle value.
expect(find.text('0'), findsOneWidget);
// Wait for the animation to complete.
await tester.pumpAndSettle(const Duration(milliseconds: 500));
// Verify that the widget ends with the final value.
expect(find.text('10'), findsOneWidget);
});
testWidgets('GetAnimatedBuilder changes value over time', (tester) async {
await tester.pumpWidget(
_Wrapper(
child: GetAnimatedBuilder<double>(
duration: const Duration(milliseconds: 500),
tween: Tween<double>(begin: 0.0, end: 1.0),
idleValue: 0.0,
builder: (context, value, child) {
return Opacity(opacity: value);
},
delay: const Duration(milliseconds: 500),
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
),
);
// Initial state is idleValue
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity, 0.0);
// Wait for the delay to finish
await tester.pump(const Duration(milliseconds: 500));
// Verify that the value changes over time
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.2, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.4, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.6, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.8, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(1.0, 0.01));
});
testWidgets('onComplete callback is called when animation finishes',
(WidgetTester tester) async {
AnimationController? controller;
var onCompleteCalled = false;
await tester.pumpWidget(
_Wrapper(
child: GetAnimatedBuilder<int>(
duration: const Duration(milliseconds: 500),
tween: Tween(begin: 0, end: 10),
idleValue: 0,
builder: (_, value, __) => Text(value.toString()),
delay: Duration.zero,
onComplete: (c) {
onCompleteCalled = true;
controller = c;
},
child: Container(),
),
),
);
expect(onCompleteCalled, isFalse);
// Wait for the animation to complete.
await tester.pumpAndSettle(const Duration(milliseconds: 500));
// Verify that the onComplete callback was called.
expect(controller, isNotNull);
expect(onCompleteCalled, isTrue);
});
testWidgets('onStart callback is called when animation starts',
(WidgetTester tester) async {
var onStartCalled = false;
await tester.pumpWidget(
_Wrapper(
child: GetAnimatedBuilder(
duration: const Duration(seconds: 1),
delay: Duration.zero,
tween: Tween<double>(begin: 0, end: 1),
idleValue: 0,
builder: (context, value, child) => Container(),
child: Container(),
onStart: (_) {
onStartCalled = true;
},
),
),
);
expect(onStartCalled, isFalse);
await tester.pump(const Duration(milliseconds: 500));
expect(onStartCalled, isTrue);
});
testWidgets('GetAnimatedBuilder delay', (WidgetTester tester) async {
await tester.pumpWidget(
_Wrapper(
child: GetAnimatedBuilder<int>(
duration: const Duration(milliseconds: 500),
tween: Tween(begin: 0, end: 10),
idleValue: 0,
builder: (_, value, __) => Text(value.toString()),
delay: const Duration(milliseconds: 500),
child: Container(),
),
),
);
// Verify that the widget starts with the idle value.
expect(find.text('0'), findsOneWidget);
// Wait for the delay to pass.
await tester.pump(const Duration(milliseconds: 500));
// Verify that the animation has started.
expect(find.text('0'), findsOneWidget);
// Wait for the animation to complete.
await tester.pumpAndSettle(const Duration(milliseconds: 500));
// Verify that the widget ends with the final value.
expect(find.text('10'), findsOneWidget);
});
testWidgets(
'FadeInAnimation in idle should be visible, but not visible when the animation starts',
(WidgetTester tester) async {
await tester.pumpWidget(
_Wrapper(
child: FadeInAnimation(
delay: const Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
idleValue: 0,
child: const Text('Hello'),
),
),
);
// in idle, the opacity should be 1.0
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity, 1.0);
// Wait for the delay to finish
await tester.pump(const Duration(milliseconds: 500));
// When the animation starts the opacity should not be visible
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity, 0.0);
// Verify that the value changes over time
await tester.pump(const Duration(milliseconds: 100));
// The value should be updated
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.2, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.4, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.6, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(0.8, 0.01));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.widget<Opacity>(find.byType(Opacity)).opacity,
closeTo(1.0, 0.01));
});
testWidgets(
'willResetOnDispose should false when fadeOut is the last animation in a sequential animation',
(WidgetTester tester) async {
await tester.pumpWidget(
_Wrapper(
child: const Text('Hello')
.fadeIn(
isSequential: true,
duration: const Duration(milliseconds: 500),
)
.fadeOut(
isSequential: true,
duration: const Duration(milliseconds: 500),
),
),
);
// The variable starts as false
expect(
tester
.state<GetAnimatedBuilderState>(find.byType(FadeOutAnimation))
.willResetOnDispose,
false);
// Jump to middle of next animation
await tester.pump(const Duration(milliseconds: 500));
// The value should be false
expect(
tester
.state<GetAnimatedBuilderState>(find.byType(FadeOutAnimation))
.willResetOnDispose,
false);
await tester.pumpAndSettle();
});
testWidgets(
'willResetOnDispose should true when fadeOut is not last animation in a sequential animation',
(WidgetTester tester) async {
await tester.pumpWidget(
_Wrapper(
child: const Text('Hello')
.fadeOut(
isSequential: true,
duration: const Duration(milliseconds: 500),
)
.fadeIn(
isSequential: true,
duration: const Duration(milliseconds: 500),
),
),
);
// The variable starts as true
expect(
tester
.state<GetAnimatedBuilderState>(find.byType(FadeOutAnimation))
.willResetOnDispose,
true);
// Jump to middle of next animation
await tester.pump(const Duration(milliseconds: 500));
// The value should be true
expect(
tester
.state<GetAnimatedBuilderState>(find.byType(FadeOutAnimation))
.willResetOnDispose,
true);
await tester.pumpAndSettle();
});
testWidgets('RotateAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
RotateAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: 0.0,
end: 360.0,
child: Container(),
),
);
expect(find.byType(RotateAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('ScaleAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
ScaleAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: 1.0,
end: 2.0,
child: Container(),
),
);
expect(find.byType(ScaleAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('SlideAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
SlideAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: Offset.zero,
end: const Offset(1.0, 1.0),
child: Container(),
),
);
expect(find.byType(SlideAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('BounceAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
BounceAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: 0.0,
end: 1.0,
child: Container(),
),
);
expect(find.byType(BounceAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('ShakeAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
ShakeAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: 0.0,
end: 10.0,
child: Container(),
),
);
expect(find.byType(ShakeAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('SpinAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
SpinAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
child: Container(),
),
);
expect(find.byType(SpinAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('ColorAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
ColorAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: Colors.blue,
end: Colors.red,
child: Container(),
),
);
expect(find.byType(ColorAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('SizeAnimation', (WidgetTester tester) async {
await tester.pumpWidget(
SizeAnimation(
duration: const Duration(seconds: 1),
delay: Duration.zero,
begin: 1.0,
end: 2.0,
child: Container(),
),
);
expect(find.byType(SizeAnimation), findsOneWidget);
await tester.pumpAndSettle();
});
}
... ...