January 31, 2026
Custom Animation in Flutter
Learn how to implement custom animations in Flutter to enhance user experience with smooth transitions and engaging effects.
In this post, I’ll explore how to implement custom animations in Flutter to create engaging and smooth transitions between screens.
What is Custom Animation?
Custom Animation in Flutter allows developers to create unique and engaging animations that enhance the user experience. Unlike predefined animations, custom animations give you full control over the animation's behavior, timing, and appearance.
Main Components of Custom Animation
- To implement Custom Animation in your Flutter app, you need to understand the following main components:

Ticker: Its like a tick / count of clock that for each tick it triggers a animation frame.AnimationController: It is like manager of the animation. It controls the animation's duration, start, stop, and reverse.Animation Value: It represents the current value of the animation at any given frame.Value is between 0.0 to 1.0.
Implementing Custom Animation
Define the Animation Controller
// Inside your StatefulWidget
class _AnimationidgetState extends State<AnimationWidget> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
lowerBound: 0.0,
upperBound: 1.0,
);
}
_controller.forward(); // Start the animation
_controller.addListener(() {
setState(() {
// Update UI
});
print(_controller.value); // Print the current animation value
});
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}- Create a variable of type
AnimationControllercalled_controller. - Initialize the controller in
initStatemethod andAnimationControllerrequiresdurationandvsyncproperties. duration: Specifies how long the animation will run.vsync: Needs aTickerProvider, which will be most of time theStateobject itself. So we addwith SingleTickerProviderStateMixinto the State class to provide the ticker.lowerBoundandupperBound: Define the range of values for the animation.thisrefers to the current State object.- As far now we got the animation controller ready and the ticker is also set up.
- To start the animation we call
_controller.forward(). - If u want to see how values are changing during the animation we can add a listener to the controller using
_controller.addListener().In console we can see the values changing from 0.0 to 1.0 during the animation. - And also we have included setState() inside the listener to update the UI on each frame.
- Finally, we dispose the controller in the
disposemethod to free up resources.
Using Animation Value to Animate Widget Properties
// Inside your build method
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: 100 + (_controller.value * 100), // Animate width from 100 to 200
height: 100 + (_controller.value * 100), // Animate height from 100 to 200
color: Colors.blue,
),
),
);
}- In the
buildmethod, we create aContainerwidget. - We use the
_controller.valueto animate thewidthandheightproperties of the Container. - As the animation progresses, the width and height of the Container will increase from 100 to 200.
Full Code Example
import 'package:flutter/material.dart';
class AnimationWidget extends StatefulWidget {
const AnimationWidget({super.key});
@override
State<AnimationWidget> createState() => _AnimationidgetState();
}
class _AnimationidgetState extends State<AnimationWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 4),
lowerBound: 0.0,
upperBound: 1.0,
);
_controller.forward(); // Start the animation
_controller.addListener(() {
setState(() {
// Update UI
});
print(_controller.value); // Print the current animation value
});
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width:
100 + (_controller.value * 100), // Animate width from 100 to 200
height:
100 + (_controller.value * 100), // Animate height from 100 to 200
color: Colors.blue,
),
),
);
}
}How to reverse the Animation
// To reverse the animation
_controller.reverse(from : 1);- Instead of using
_controller.forward()to start the animation, you can use_controller.reverse()to reverse the animation from the end to the beginning. - Its important to define
fromproperty to specify the starting point of the reverse animation.
How to Loop the Animation
- In order to loop the animation , we need to know when the animation is completed or dismissed.
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.reverse();
} else if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});- We can use
addStatusListenermethod of the controller to listen for animation status changes. - When the animation status is
completed, we call_controller.reverse()to reverse the animation - When the animation status is
dismissed, we call_controller.forward()to start the animation again.
Curve animations
- As far now we have seen linear animations where the animation progresses at a constant rate.
- But in real world most of the animations are not linear, they have acceleration and deceleration effects.
- Flutter provides
CurvedAnimationclass to apply different easing curves to the animation.
Using CurvedAnimation
// Inside your StatefulWidget
late Animation _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut, // Apply easeInOut curve
);
_controller.forward();
}- We create a variable of type
Animationcalled_animation. - We initialize the
_animationusingCurvedAnimationclass. parent: We pass the_controlleras the parent of the curved animation.curve: We specify the easing curve we want to apply. In this case, we useCurves.easeInOutfor a smooth acceleration and deceleration effect.- we cannot use
lowerBoundandupperBoundproperties withCurvedAnimation, because the curve itself defines the range of values.So we remove those properties from theAnimationController. - Check Curves Documentation
Tween Animation.
- Tween stands for "in-between" and it defines how to transition from a starting value to an ending value.
- Tween animations are useful when you want to animate properties that are not just simple numeric values, such as colors, sizes, or positions.
Using Tween Animation
// Inside your StatefulWidget
late Animation<Color?> _colorAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_colorAnimation = ColorTween(
begin: Colors.red,
end: Colors.blue,
).animate(_controller);
_controller.forward();
}- We create a variable of type
Animation<Color?>called_colorAnimation. - We initialize the
_colorAnimationusingColorTweenclass. begin: We specify the starting color of the animation.end: We specify the ending color of the animation.- We call the
animatemethod on theColorTweenand pass the_controllerto link the tween animation with the animation controller.
Using Tween Animation Value in Widget
// Inside your build method
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: 100,
height: 100,
color: _colorAnimation.value, // Use the tween animation value
),
),
);
}- In the
buildmethod, we create aContainerwidget. - We use the
_colorAnimation.valueto set thecolorproperty of the Container - As the animation progresses, the color of the Container will transition from red to blue.
- There are many tween classes available in Flutter like
SizeTween,RectTween,IntTween,Tween<double>, etc. You can choose the appropriate tween class based on the property you want to animate.
Recommended for you
Jan 29, 2026
State Management using Provider and Hive in Flutter
This Blog is about how to use Hive in a Flutter app to persist data locally by building a simple shopping list.
Jan 22, 2026
Understanding Hive in Flutter || Building a Persistent Shopping List
This Blog is about how to use Hive in a Flutter app to persist data locally by building a simple shopping list.