Built-In Explicit Animations
What are Built In Explicit Animations ??
According to the official documentation
The Flutter SDK also provides built-in explicit animations, such as
FadeTransition
,SizeTransition
, andSlideTransition
.
These simple animations are triggered by setting a beginning and ending point.
Some of the control of the animation is given to the user or programmer
Let’s talk about the explicit built in animation in details with examples
Before starting the deep dive
Let me explain you some things
i ) Ticker Provider State Mixin :
The ticker provider state mixin is used to provide a new tick on every change in the animation
The ticker provider state mixin are of two types
i ) Single Ticker Provider State Mixin :
The single ticker provider state mixin is used with only one controller
If you are managing all of the animation on the screen with a single controller then use the single ticker provider state mixin
ii ) Ticker Provider State Mixin :
The ticker provider state mixin is used for more than one controller
If you are managing the animations on the screen with a more than one controller’s then use the ticker provider state mixin
i ) Animation Controller :
Animation controller is the controller for the animation .
It provides us the control on the animation about how and when to start , stop , dismiss , reverse the animation
According to the official documentation
An AnimationController linearly produces values that range from 0.0 to 1.0, during a given duration. The animation controller generates a new value whenever the device running your app is ready to display a new frame (typically, this rate is around 60 values per second).
Follow these steps to create an animation controller
i ) Declare the Animation Controller :
late AnimationController _animationController;
Declare the animation controller using late
ii ) Initialize the Animation controller :
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
}
Initialize the animation controller in the initial state of the state of the state full life cycle
The animation controller provides us a lot of method’s that help’s us to control the animation that we should discuss later
. Duration :
The Duration property of the animation controller is used to duration of the animation
. Vsync :
vsync is used to sync the animation controller with the ticker provider
iii ) Dispose The Animation Controller :
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
Dispose the animation controller in the dispose method of the state of the state full life cycle
iii ) Tween :
Make a tween which will provide the value to the animation
The word tween derives from the “Between” which provides us the values between the range (starting and ending ) value
iv ) Animation :
i ) Declare the animation :
Declare the animation reference variable and initialize it later
ii ) Initialize the animation variable :
Initialize the animation variable using late in the initial state of the state of the state full widget
_animation = tween.animate(_animationController);
Now let’s talk about how to perform these animation or how to use these properties
The transition’s are used to to perform the built in explicit animations
“Transition” means the movement of things from one position to another
Let’s deep dive into the transition’s
i ) Rotation Transition :
The rotation transition is used to rotate the given child widget in clockwise direction
RotationTransition RotationTransition({
Key? key,
required Animation<double> turns,
Alignment alignment = Alignment.center,
FilterQuality? filterQuality,
Widget? child,
})
. Turns :
The turns property are used to set the number of the turns of the animation . One turn is used to rotate the widget to 360 degree
import 'package:flutter/material.dart';
class RotationTransitionDesign extends StatefulWidget {
const RotationTransitionDesign({super.key});
@override
State<RotationTransitionDesign> createState() =>
_RotationTransitionDesignState();
}
class _RotationTransitionDesignState extends State<RotationTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
Tween<double> tween = Tween<double>(begin: 0, end: 1);
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void rotateContainer() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Rotated Transition Design"),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RotationTransition(
turns: _animation,
child: Container(
width: 300,
height: 300,
color: Colors.purple,
),
)
],
),
),
floatingActionButton: FloatingActionButton(onPressed: rotateContainer),
);
}
}
On the click event of the floating action button . I rotate the container and then reverse it . mean’s first it start’s moving in clock wise direction then it will move back in anti clock wise direction
The forward method of the animation is used to start the animation for the first time
The reverse method of the animation controller is used to reverse the animation or start’s from the ending and end it on the starting point
For more information about the animation controller .
Kindly read it from the official documentation or you may get some knowledge from my article on animation controller
ii ) Scale Transition :
The scale transition is used to scale the given child widget or change the size of the given widget
ScaleTransition ScaleTransition({
Key? key,
required Animation<double> scale,
Alignment alignment = Alignment.center,
FilterQuality? filterQuality,
Widget? child,
})
The original scale of the scale of the widget is 1 . if the scale is increased to 2 then the widget will become double of it’s size
import 'package:flutter/material.dart';
class ScaleTransitionDesign extends StatefulWidget {
const ScaleTransitionDesign({super.key});
@override
State<ScaleTransitionDesign> createState() => _ScaleTransitionDesignState();
}
class _ScaleTransitionDesignState extends State<ScaleTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
Tween<double> tween = Tween<double>(begin: 1, end: 2);
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void scaleContainer() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Scale Transition Design"),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ScaleTransition(
scale: _animation,
child: Icon(
Icons.favorite,
color: Colors.red,
size: 350,
),
)
],
),
),
floatingActionButton: FloatingActionButton(onPressed: scaleContainer),
);
}
}
On the click event of the floating action button i change the scale of the icon of heart (favorite)
iii ) Align Transition :
The align transition animation is used to change the animation of the given widget
AlignTransition AlignTransition({
Key? key,
required Animation<AlignmentGeometry> alignment,
required Widget child,
double? widthFactor,
double? heightFactor,
})
The Alignment property is used to set the alignment of the given widget
The width and the height factor is used to set the width and the height of the given if it is not mentioned
import 'package:flutter/material.dart';
class AlignTransitionDesign extends StatefulWidget {
const AlignTransitionDesign({super.key});
@override
State<AlignTransitionDesign> createState() => _AlignTransitionDesignState();
}
class _AlignTransitionDesignState extends State<AlignTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Alignment> _animation;
Tween<Alignment> tween =
Tween<Alignment>(begin: Alignment.topLeft, end: Alignment.bottomRight);
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeContainerAlignment() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Align Transition Design"),
centerTitle: true,
),
body: Center(
child: AlignTransition(
alignment: _animation,
child: Container(
width: 200,
height: 200,
color: Colors.purple,
)),
),
floatingActionButton:
FloatingActionButton(onPressed: changeContainerAlignment),
);
}
}
On the click event of the floating action button i change the alignment of the container from the top left to bottom right and then vice versa .
iv ) Decorated Box Transition :
Decorated box transition is used to set the decoration of the decorated box
This will animate the border radius , shadows , colors , and multiple things of the decorated box .
DecoratedBoxTransition DecoratedBoxTransition({
Key? key,
required Animation<Decoration> decoration,
DecorationPosition position = DecorationPosition.background,
required Widget child,
})
Box decoration is used to decorate pr animated the container’s decorated box
import 'package:flutter/material.dart';
class DecoratedBoxTransitionDesign extends StatefulWidget {
const DecoratedBoxTransitionDesign({super.key});
@override
State<DecoratedBoxTransitionDesign> createState() =>
_DecoratedBoxTransitionDesignState();
}
class _DecoratedBoxTransitionDesignState
extends State<DecoratedBoxTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Decoration> _animation;
DecorationTween decorationTween = DecorationTween(
begin: BoxDecoration(
borderRadius: BorderRadius.circular(70), color: Colors.amber),
end: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.purple));
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = decorationTween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeContainerDecoration() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Decorated Box Transition Design"),
centerTitle: true,
),
body: Center(
child: DecoratedBoxTransition(
decoration: _animation,
child: Container(
width: 800,
height: 800,
)),
),
floatingActionButton: FloatingActionButton(onPressed: changeContainerDecoration),
);
}
}
On the click event of the floating action button . I animate the decoration of the container
If you want’s more information about the decorated box of the container in detail’s
Kindly read it from the official documentation or you may get knowledge from my article on container widget in which i try to guide in detail about the decorated box
v ) Default Text Style Transition :
Default text style transition is used to animate the text by changing it’s text style
DefaultTextStyleTransition DefaultTextStyleTransition({
Key? key,
required Animation<TextStyle> style,
required Widget child,
TextAlign? textAlign,
bool softWrap = true,
TextOverflow overflow = TextOverflow.clip,
int? maxLines,
})
If you want’s more information about the text style kindly read it from the official documentation or you may also get information about the text style from my article on it
import 'package:flutter/material.dart';
class DefaultTextStyleTransitionDesign extends StatefulWidget {
const DefaultTextStyleTransitionDesign({super.key});
@override
State<DefaultTextStyleTransitionDesign> createState() =>
_DefaultTextStyleTransitionDesignState();
}
class _DefaultTextStyleTransitionDesignState
extends State<DefaultTextStyleTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<TextStyle> _animation;
TextStyleTween tween = TextStyleTween(
begin: TextStyle(
color: Colors.pink,
fontStyle: FontStyle.italic,
fontSize: 50,
fontWeight: FontWeight.normal),
end: TextStyle(
color: Colors.purple,
fontSize: 100,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold));
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeTextStyle() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Default Text Style Transition Design"),
centerTitle: true,
),
body: Center(
child: DefaultTextStyleTransition(
style: _animation, child: Text("Hi Abubakar")),
),
floatingActionButton: FloatingActionButton(onPressed: changeTextStyle),
);
}
}
On the click event of the floating Action Button i will animate the text by changing it’s text style
vi ) Fade Transition :
Fade Transition is used to change the opacity or to animate the given widget using the fade in or fade out
FadeTransition FadeTransition({
Key? key,
required Animation<double> opacity,
bool alwaysIncludeSemantics = false,
Widget? child,
})
The opacity is used to set the fade value
The opacity of zero mean’s fully opaque or fully visible
The opacity of 1 mean’s fully transparent
import 'package:flutter/material.dart';
class FadeTransitionDesign extends StatefulWidget {
const FadeTransitionDesign({super.key});
@override
State<FadeTransitionDesign> createState() => _FadeTransitionDesignState();
}
class _FadeTransitionDesignState extends State<FadeTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
Tween<double> tween = Tween<double>(begin: 1, end: 0);
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeContainerOpacity() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Fade Transition Design"),
centerTitle: true,
),
body: Center(
child: FadeTransition(
opacity: _animation,
child: Container(
width: 800,
height: 800,
color: Colors.amber,
)),
),
floatingActionButton: FloatingActionButton(onPressed: changeContainerOpacity),
);
}
}
On the click event of the floating action button . i will change the opacity of the given child container from 1 to 0 and then vice versa
vii ) Positioned Transition Animation :
The positioned transitioned animation is used to perform the animation by changing the position of the given child widget in the parent
PositionedTransition PositionedTransition({
Key? key,
required Animation<RelativeRect> rect,
required Widget child,
})
According to the official documentation
The positioned transitioned must be used inside the Stack Widget
Relative rect is used to set the positioned of the given child widget while animating it
If you wan’t more information about the positioned transition widget kindly read it from the official documentation or you may also get knowledge from my article on relative rect
According to the official documentation
An immutable 2D, axis-aligned, floating-point rectangle whose coordinates are given relative to another rectangle’s edges, known as the container. Since the dimensions of the rectangle are relative to those of the container, this class has no width and height members.
import 'package:flutter/material.dart';
class PositionedTransitionedDesign extends StatefulWidget {
const PositionedTransitionedDesign({super.key});
@override
State<PositionedTransitionedDesign> createState() =>
_PositionedTransitionedDesignState();
}
class _PositionedTransitionedDesignState
extends State<PositionedTransitionedDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<RelativeRect> _animation;
RelativeRectTween relativeRectTween = RelativeRectTween(
begin: RelativeRect.fromSize(Rect.fromLTWH(0, 0, 200, 200), Size(10, 10)),
end: RelativeRect.fromSize(
Rect.fromLTWH(1500, 900, 200, 200), Size(20, 20)));
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = relativeRectTween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeContainerPosition() async {
await _animationController.forward();
_animationController.reverse();
// _animationController.repeat();
}
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.sizeOf(context);
var screenWidth = screenSize.width;
var screenHeight = screenSize.height;
var clientHeight = screenHeight - kToolbarHeight;
return Scaffold(
appBar: AppBar(
title: Text("Positioned Transition Design"),
centerTitle: true,
),
body: Container(
width: screenWidth,
height: clientHeight,
color: Colors.white,
child: Stack(
children: [
PositionedTransition(
rect: _animation,
child: Text(
"Abubakar",
style: TextStyle(
fontSize: 30,
color: Colors.amber,
fontWeight: FontWeight.bold),
)),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: changeContainerPosition),
);
}
}
On the click event of the floating action button i will animate the given child container by changing the position of that widget inside the stack
viii ) Relative Positioned Transition :
The relative positioned transition is similar as the positioned transition but the only difference is that the
RelativePositionedTransition RelativePositionedTransition({
Key? key,
required Animation<Rect?> rect,
required Size size,
required Widget child,
})
Relative Rect is used in simple positioned transition and the only rect is used to set the positioned of the given child widget in the stack for relative positioned transition
import 'package:flutter/material.dart';
class RelativePositionedTransitionedDesign extends StatefulWidget {
const RelativePositionedTransitionedDesign({super.key});
@override
State<RelativePositionedTransitionedDesign> createState() =>
_RelativePositionedTransitionedDesignState();
}
class _RelativePositionedTransitionedDesignState
extends State<RelativePositionedTransitionedDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Rect?> _animation;
RectTween relativeRectTween = RectTween(
begin: Rect.fromLTWH(0, 0, 200, 200),
end: Rect.fromLTWH(1500, 900, 200, 200));
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = relativeRectTween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void changeContainerPosition() async {
await _animationController.forward();
_animationController.reverse();
// _animationController.repeat();
}
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.sizeOf(context);
var screenWidth = screenSize.width;
var screenHeight = screenSize.height;
var clientHeight = screenHeight - kToolbarHeight;
return Scaffold(
appBar: AppBar(
title: Text("Relative Positioned Transition Design"),
centerTitle: true,
),
body: Container(
width: screenWidth,
height: clientHeight,
color: Colors.white,
child: Stack(
children: [
RelativePositionedTransition(
rect: _animation,
child: Text("Abubakar"),
size: Size(200, 200),
),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: changeContainerPosition),
);
}
}
If you wan’t more information about the Rect kindly read it from the official documentation or you may also get knowledge from my article on it
On the click event of the floating action button i change the position of the given child text
ix ) Size Transition :
The size transition is used to animate the given child by cropping the size of the given child widget
According to the official documentation
Animates its own size and clips and aligns its child.
SizeTransition acts as a ClipRect that animates either its width or its height, depending upon the value of axis. The alignment of the child along the axis is specified by the axis Alignment.
SizeTransition SizeTransition({
Key? key,
Axis axis = Axis.vertical,
required Animation<double> sizeFactor,
double axisAlignment = 0.0,
Widget? child,
})
Axis is sued to set whether the animation will be perform by clipping the given child in vertical direction or horizontal direction
size factor is used to set the size that how should it will be clipped
import 'package:flutter/material.dart';
class SizeTransitionDesign extends StatefulWidget {
const SizeTransitionDesign({super.key});
@override
State<SizeTransitionDesign> createState() => _SizeTransitionDesignState();
}
class _SizeTransitionDesignState extends State<SizeTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
Tween<double> tween = Tween<double>(begin: 0, end: 1);
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 600));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void startAnimation() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Size Transition Design"),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizeTransition(
sizeFactor: _animation,
child: Icon(
Icons.favorite,
size: 500,
color: Colors.red,
)),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: startAnimation),
);
}
}
On the click event of the floating action button i start’s the animation .
The animation start’s from clipping the icon of heart until the center and then vice versa
x ) Slide Transition :
The slide transition is used to slide the given child in either horizontal or vertical direction
SlideTransition SlideTransition({
Key? key,
required Animation<Offset> position,
bool transformHitTests = true,
TextDirection? textDirection,
Widget? child,
})
The offset’s are used to slide the given child in the parent
The offset are the point’s on the cartesian plane . Offset (x, y)
According to the official documentation
For example, an Offset with a dx of 0.25 will result in a horizontal translation of one quarter the width of the child.
The value of 1 will move full of the length along the given side
import 'package:flutter/material.dart';
class SlideTransitionDesign extends StatefulWidget {
const SlideTransitionDesign({super.key});
@override
State<SlideTransitionDesign> createState() => _SlideTransitionDesignState();
}
class _SlideTransitionDesignState extends State<SlideTransitionDesign>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Offset> _animation;
// According to the official documentation
// For example, an Offset with a dx of 0.25 will result in a horizontal translation of one quarter the width of the child.
Tween<Offset> tween = Tween<Offset>(begin: Offset(-2, -2), end: Offset(2, 2));
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(seconds: 2));
_animation = tween.animate(_animationController);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void slideContainer() async {
await _animationController.forward();
_animationController.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Slide Transition Design"),
centerTitle: true,
),
body: Center(
child: SlideTransition(
position: _animation,
child: Container(
width: 200,
height: 200,
color: Colors.pink,
),
),
),
floatingActionButton: FloatingActionButton(onPressed: slideContainer),
);
}
}
On the click event of the floating action button . i will slide the given child container in both horizontal and vertical directions
That’s all for the built in explicit animation
I hope you learned a lot of new things 📚
Thanks for reading 😊