In this article, we discuss the most used animation widget in Flutter that Developers should know about in 2024
Flutter’s animation capabilities elevate your app from static to dynamic. Discover the most used animation widgets and bring your UI to life with smooth transitions, engaging interactions, and captivating effects.
Animations are the magic sauce that adds a sprinkle of life and interactivity to your Flutter app. They not only enhance the user experience but also make your app stand out from the competition. With Flutter’s rich animation framework, you have a plethora of widgets at your disposal to create stunning visual effects.
But with so many options, where do you start? This blog post dives into the top Flutter animation widgets that are widely used and incredibly versatile. We’ll explore their functionalities, showcase real-world examples, and provide everything you need to unleash your inner animation maestro.
Table of Contents
AnimatedContainer
This powerhouse widget seamlessly animates any container property, be it opacity, color, size, or even transformations like rotation and skew. Imagine a button that pulses when pressed or a progress bar that dynamically fills with color. AnimatedContainer makes these effects effortless.
Demo
Code
import 'package:flutter/material.dart';
class AnimatedContainerExample extends StatefulWidget {
const AnimatedContainerExample({super.key});
@override
State<AnimatedContainerExample> createState() => _AnimatedContainerExampleState();
}
class _AnimatedContainerExampleState extends State<AnimatedContainerExample> {
bool selected = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated Container')),
body: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Center(
child: AnimatedContainer(
width: selected ? 200.0 : 100.0,
height: selected ? 100.0 : 200.0,
color: selected ? Colors.red : Colors.blue,
alignment: selected ? Alignment.center : AlignmentDirectional.topCenter,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: const FlutterLogo(size: 75),
),
),
),
);
}
}
AnimatedPositioned
Need to move your widgets around with flair? AnimatedPositioned takes care of that. Animate the position, size, and alignment over a specified duration, creating smooth transitions and dynamic layouts. Think of expanding menus, sliding panels, or even playful character movements.
Demo
Code
import 'package:flutter/material.dart';
class AnimatedPositionedExample extends StatefulWidget {
const AnimatedPositionedExample({super.key});
@override
State<AnimatedPositionedExample> createState() => _AnimatedPositionedExampleState();
}
class _AnimatedPositionedExampleState extends State<AnimatedPositionedExample> {
bool selected = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated Positioned')),
body: Center(
child: SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: const ColoredBox(
color: Colors.blue,
child: Center(child: Text('Tap me')),
),
),
),
],
),
),
),
);
}
}
AnimatedCrossFade
Flawless transitions between screens are a hallmark of a polished app. AnimatedCrossFade handles this with grace, smoothly fading out one widget while fading in another. This is perfect for page transitions, loading screens, or revealing hidden content with a tap.
Demo
Code
import 'package:flutter/material.dart';
class AnimatedCrossFadeExample extends StatefulWidget {
@override
AnimatedCrossFadeExampleState createState() => AnimatedCrossFadeExampleState();
}
class AnimatedCrossFadeExampleState extends State<AnimatedCrossFadeExample> {
bool _firstChild = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated CrossFade')),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(16.0),
width: double.infinity,
height: 60,
color: Colors.orange.shade200,
),
AnimatedCrossFade(
firstCurve: Curves.easeInCubic,
secondCurve: Curves.easeInCirc,
firstChild: InkWell(
onTap: () {
setState(() {
_firstChild = !_firstChild;
});
},
child: Container(
child: ClipOval(
child: CircleAvatar(
maxRadius: 100,
child: FlutterLogo(size: 200),
),
),
alignment: Alignment.center,
),
),
secondChild: InkWell(
onTap: () {
setState(() {
_firstChild = !_firstChild;
});
},
child: Container(
height: 250,
width: 250,
child: FlutterLogo(),
color: Colors.amberAccent.shade700,
),
),
crossFadeState: _firstChild ? CrossFadeState.showFirst : CrossFadeState.showSecond,
duration: Duration(seconds: 2),
layoutBuilder: (
Widget topChild,
Key topChildKey,
Widget bottomChild,
Key bottomChildKey,
) {
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
PositionedDirectional(
child: bottomChild,
key: bottomChildKey,
top: 0,
),
PositionedDirectional(
child: topChild,
key: topChildKey,
),
],
);
},
),
Container(
margin: EdgeInsets.all(16.0),
width: double.infinity,
height: 60,
color: Colors.red.shade200,
),
],
),
),
);
}
}
AnimatedOpacity
Sometimes, subtle hints are all you need. AnimatedOpacity gently fades your widget in or out, creating a discreet yet impactful effect. Use it to highlight important elements, indicate loading states, or even implement ghost buttons that appear on hover.
Demo
Code
import 'package:flutter/material.dart';
class AnimateOpacityExample extends StatefulWidget {
const AnimateOpacityExample({super.key});
@override
State<AnimateOpacityExample> createState() => AnimateOpacityExampleState();
}
class AnimateOpacityExampleState extends State<AnimateOpacityExample> {
double opacityLevel = 1.0;
void _changeOpacity() {
setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated Opacity')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
AnimatedOpacity(
opacity: opacityLevel,
duration: const Duration(seconds: 3),
child: const FlutterLogo(size: 200),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: _changeOpacity,
child: const Text('Fade Logo'),
),
],
),
),
);
}
}
AnimatedBuilder
For complex animations that involve rebuilding parts of your widget tree, AnimatedBuilder comes to the rescue. It rebuilds only the affected portions based on animation values, resulting in efficient and performant animations. Think of dynamically changing text based on user input or animating complex data visualizations.
Demo
Code
import 'package:flutter/material.dart';
import 'dart:math' as math;
class AnimatedBuilderExample extends StatefulWidget {
const AnimatedBuilderExample({super.key});
@override
State<AnimatedBuilderExample> createState() => _AnimatedBuilderExampleState();
}
/// AnimationControllers can be created with `vsync: this` because of
/// TickerProviderStateMixin.
class _AnimatedBuilderExampleState extends State<AnimatedBuilderExample> with TickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..repeat();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated Container')),
body: Center(
child: AnimatedBuilder(
animation: _controller,
child: Container(
width: 200.0,
height: 200.0,
color: Colors.green,
child: const Center(
child: Text(
'Flutter',
style: TextStyle(fontSize: 20),
),
),
),
builder: (BuildContext context, Widget? child) {
return Transform.rotate(
angle: _controller.value * 2.0 * math.pi,
child: child,
);
},
),
),
);
}
}
GitHub
Click here to download the Full Code