✨ Implicit Animations — Make Your Tiles Come Alive!
🧒 Why Do My Tiles Change Instantly? (The Flip Book Analogy!)
Right Now, Your Tiles "Snap" — Like Turning a Light Switch
When you submit a guess, the tiles change from white to green/yellow/gray instantly. It's functional, but it feels... abrupt. Like a light switch going from OFF to ON with nothing in between.
Implicit animations are like a dimmer switch — instead of snapping instantly, the color smoothly fades from old to new over a short time. It's the difference between a cheap toy and a polished, professional app!
- ✅ You'll discover what "implicit animations" are
- ✅ You'll convert your Container to AnimatedContainer
- ✅ You'll control timing with Duration
- ✅ You'll customize the feel with Curves
- ✅ Your tiles will smoothly transition between colors!
Implicit vs Explicit — The "Just Tell Me What" Approach
Flutter has two ways to animate things. The easy one is implicit animations:
Implicit Animation
You just say WHAT you want. "I want the color to be green now." Flutter figures out the HOW — it smoothly animates from the old color to green automatically.
Example: AnimatedContainer, AnimatedOpacity
Explicit Animation
You control everything. You set up an AnimationController, define tweens, and manually control every frame. More power, but more work.
Example: AnimationController + Tween
For 90% of animations, implicit is all you need. Today you'll learn AnimatedContainer — it's just like Container, but with animation superpowers!
Duration & Curves — The Speed and Feel of Your Animation
Two simple things control how your animation looks and feels:
Duration
How LONG the animation takes. Duration(milliseconds: 500) = half a second. Shorter = snappy, longer = dramatic.
Curve
How the animation SPEEDS UP or SLOWS DOWN. Linear = constant speed. BounceIn = springs in. EaseOut = starts fast, ends slow.
With just these two properties, you can create dozens of different animation feels — all without writing any complex animation code!
1 The Magic Change — Container → AnimatedContainer
Here's the beautiful thing: AnimatedContainer is a drop-in replacement for Container. All the same properties work — you just add animation timing!
Step 1.1 BEFORE: Your Current Tile (Instant Change)
Here's your current Tile widget using a regular Container:
return Container( // ← Regular Container
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
color: switch (hitType) {
HitType.hit => Colors.green,
HitType.partial => Colors.yellow,
HitType.miss => Colors.grey,
_ => Colors.white,
},
),
child: Center(
child: Text(
letter.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
),
),
);
When hitType changes, the color snaps instantly — white → green in 0 seconds. Functional, but jarring.
Step 1.2 AFTER: AnimatedContainer (Smooth Transition!)
Change just one word and add one line. That's it!
return AnimatedContainer( // ← CHANGED: "Animated" added!
duration: Duration(milliseconds: 500), // ← NEW: animation takes 0.5 seconds
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
color: switch (hitType) {
HitType.hit => Colors.green,
HitType.partial => Colors.yellow,
HitType.miss => Colors.grey,
_ => Colors.white,
},
),
child: Center(
child: Text(
letter.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
),
),
);
That's literally it! Two changes:
Container→AnimatedContainer— The widget now has animation powers.duration: Duration(milliseconds: 500)— Tells Flutter: "Animate ALL property changes over half a second."
Everything else — height, width, decoration, child — stays exactly the same. AnimatedContainer knows how to smoothly transition between old and new values for all of them!
setState is called in GamePage, Flutter rebuilds the Tile with a new hitType. AnimatedContainer notices: "Oh! The color property changed from white to green. Let me animate that smoothly over 500ms!" It automatically calculates all the in-between colors and renders them frame by frame.
Step 1.3 Understanding Duration — Milliseconds, Seconds, and More
The Duration class is how Flutter measures time. Here are the different ways you can write it:
Duration(milliseconds: 500) |
Half a second (most common) |
Duration(seconds: 1) |
One full second (dramatic) |
Duration(milliseconds: 250) |
Quarter second (snappy) |
Duration(seconds: 2, milliseconds: 300) |
2.3 seconds (you can combine units!) |
Duration(minutes: 1) |
One minute (please don't use this for animations 😅) |
Rule of thumb: Most UI animations should be between 200ms and 500ms. Faster than 200ms feels instant. Slower than 500ms feels sluggish.
2 Animation Curves — Change the "Feel" of Your Animation
By default, animations run at a constant speed (linear). But you can make them speed up, slow down, bounce, or spring using Curves!
Step 2.1 The Default: Linear (Constant Speed)
Without specifying a curve, Flutter uses Curves.linear — the animation moves at the same speed from start to finish:
Imagine a car driving at exactly 30mph the whole trip. 🚗💨 Boring but predictable.
Step 2.2 Add a Bounce Curve — Make It Fun!
Add just one more line to your AnimatedContainer:
return AnimatedContainer(
duration: Duration(milliseconds: 500),
curve: Curves.bounceIn, // ← NEW! Makes the color "bounce" in
height: 60,
width: 60,
decoration: BoxDecoration(/* ... */),
child: Center(/* ... */),
);
Hot reload and submit a guess. The tiles now bounce into their new color — it feels playful and satisfying!
Step 2.3 Curve Cheat Sheet — Try These!
Here are the most useful curves. Try each one by replacing Curves.bounceIn:
Curves.easeIn
Starts slow, then speeds up. Like a car accelerating from a stop.
Curves.easeOut
Starts fast, then slows down. Like a car gently braking.
Curves.easeInOut
Slow start, fast middle, slow end. The most natural-feeling curve.
Curves.bounceOut
Bounces at the END of the animation. Like a ball settling down.
Curves.elasticIn
Stretches like a rubber band before snapping in. Dramatic!
Curves.fastOutSlowIn
Material Design standard. Fast start, very gradual end.
Curves.easeInOut is the most professional choice for most UI animations.
Curves.bounceIn adds personality — great for games!
Avoid Curves.elasticIn for serious business apps — it's too playful.
3 What Else Can You Animate? — AnimatedContainer Superpowers
AnimatedContainer doesn't just animate colors — it animates almost every property a regular Container has!
Step 3.1 Everything AnimatedContainer Can Animate
Any of these properties, when changed, will smoothly animate to their new values:
Size
width, height — Make a box grow or shrink smoothly.
Color
color in BoxDecoration — Fade between any two colors.
Border Radius
borderRadius — Morph from square to circle!
Alignment
alignment — Slide a child from one position to another.
Padding & Margin
padding, margin — Expand or contract spacing.
Shadow
boxShadow — Animate shadows appearing or deepening.
The magic: You don't write ANY animation code for these. Just change the property, and AnimatedContainer handles the smooth transition automatically!
Step 3.2 Other Implicit Animation Widgets
AnimatedContainer is just one of many implicit animation widgets. Here are others you'll use:
AnimatedOpacity |
Fade widgets in and out |
AnimatedPadding |
Animate padding changes |
AnimatedAlign |
Animate alignment position |
AnimatedDefaultTextStyle |
Animate text style changes |
AnimatedSwitcher |
Animate between two completely different widgets |
They all follow the same pattern: Give them a new value, and they animate the transition automatically!
📝 What You Learned Today
You just added professional polish to your app with minimal code!
Discovered Implicit Animations
Implicit animations handle the "how" of animation — you just specify the new state and the widget animates automatically.
Used AnimatedContainer
Replaced Container with AnimatedContainer — tiles now smoothly transition between colors in half a second.
Customized with Curves
Added Curves.bounceIn for playful bouncing animations. Learned 6+ curve options for different feels.
Completed the Birdle Game!
Your Birdle game now has custom widgets, layouts, input, state management, AND smooth animations. 🎉
🧠 Test Yourself!
Let's check your animation knowledge:
Q1 What widget can you use to automatically animate changes to properties like color, size, and decoration?
Q2 What does the duration property control in an AnimatedContainer?
📦 Project 1: Animated Size Changer
Use AnimatedContainer to create a box that smoothly grows and shrinks when tapped!
Objective: Tap to Grow/Shrink a Box
📋 Requirements:
- Create a StatefulWidget called
SizeAnimator - Have a
bool _isBig = false;state variable - Use AnimatedContainer with:
duration: Duration(milliseconds: 300)curve: Curves.easeInOut- Width:
_isBig ? 200 : 100 - Height:
_isBig ? 200 : 100 - Color:
_isBig ? Colors.blue : Colors.red borderRadius: BorderRadius.circular(_isBig ? 40 : 10)
- Wrap in GestureDetector — onTap, call
setState(() { _isBig = !_isBig; })
🎯 Expected Output:
A colored square that smoothly animates between small/red/square-ish and big/blue/round when tapped. Size, color, AND border radius all animate simultaneously!
📦 Project 2: Animated Progress Bar
Build a smooth loading bar that fills up when tapped — great for understanding AnimatedContainer!
Objective: Build a Fill Animation
📋 Requirements:
- Create a StatefulWidget called
ProgressBar - Have a
double _progress = 0.0;state variable - Build a layout with:
- A Text showing "Progress: X%" where X =
(_progress * 100).toInt() - A Container (the track) with gray background, height: 30, full width
- Inside the track, use FractionallySizedBox with
widthFactor: _progress - Inside that, an AnimatedContainer with blue color that fills the fraction
- A Text showing "Progress: X%" where X =
- Add an ElevatedButton — each tap adds 0.1 to progress (up to 1.0)
- Use
duration: Duration(milliseconds: 400)andcurve: Curves.easeOut
🎯 Expected Output:
A progress bar that smoothly fills from 0% to 100% as you tap the button. The animated container slides the fill width smoothly!
GestureDetector or just use a button below.Lesson Complete!
You added smooth, professional animations to your Birdle game with just two lines of code. This completes the Introduction to Flutter UI — you've built a fully functional, polished game!
Click the button above to track your progress!