Day 19: Bringing Your App to Life with Animations
A static app is like a silent film—it can tell a story, but it lacks life. Animations are the sound, color, and emotion of your UI. They guide the user’s eye, provide feedback, and create a delightful, polished experience. Today, we’ll become digital animators.
Easy Mode: Implicit Animations
Implicit animations are Flutter’s “set it and forget it” solution. You don’t describe the animation itself; you just tell a widget its new properties (like a new color or size). The widget is smart enough to figure out how to smoothly animate from its old state to the new one over a given duration.
The most famous of these is AnimatedContainer
. It’s just like a regular Container
, but when you change its properties, it animates the difference automatically.
Live Simulation: The Magic Container
Change Its Properties:
bool selected = false;
AnimatedContainer(
width: selected ? 200.0 : 100.0,
height: selected ? 100.0 : 200.0,
color: selected ? Colors.blue : Colors.red,
alignment: selected ? Alignment.center : Alignment.topCenter,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: const FlutterLogo(size: 75),
);
Pro Mode: Explicit Animations
Sometimes you need more control. You might want an animation to loop forever, go in reverse, or follow a complex sequence. For this, you need Explicit Animations. Think of yourself as a movie director. You get an AnimationController
to manage the timeline (play, pause, stop), and a Tween
(short for “in-between”) to define the start and end values of what you’re animating (e.g., from 0 degrees to 360 degrees).
Live Simulation: The Spinning Icon
Animation Controls:
// 1. Controller manages the animation's time
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this, // Prevents offscreen animations
)..repeat(); // Loop forever
// 2. AnimatedBuilder rebuilds the widget on every tick
AnimatedBuilder(
animation: _controller,
child: /* your icon widget */,
builder: (BuildContext context, Widget? child) {
return Transform.rotate(
angle: _controller.value * 2.0 * math.pi,
child: child,
);
},
)
The Magic Trick: Hero Animations
Hero animations create one of the most beautiful effects in mobile UI: a shared element transition. It looks like a widget “flies” from one screen to another, seamlessly connecting the two. It’s perfect for transitioning from a list item to a detail page.
The magic is surprisingly simple. You just wrap the widget on both the starting screen and the destination screen in a Hero
widget, and—this is the crucial part—give them both the **exact same `tag`**. Flutter handles the rest.
Live Simulation: Profile Picture Transition
Contacts
Alex Doe
Alex Doe
Flutter Developer
The Code:
// On the first screen (List View)
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return DetailScreen();
}));
},
child: Hero(
// The tag MUST be unique for this item
tag: 'avatar-alex',
child: CircleAvatar(
backgroundImage: NetworkImage('...'),
),
),
);
// On the second screen (Detail View)
Hero(
// The tag MUST be the same as on the first screen
tag: 'avatar-alex',
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(...),
),
);