Hero animations help make screen changes smooth by moving a widget from one page to another. This makes the app feel connected and natural.
Hero animations in Flutter
Hero(
tag: 'uniqueTag',
child: WidgetToAnimate(),
)The tag must be the same on both source and destination widgets.
The child is the widget that will animate between screens.
Hero( tag: 'imageHero', child: Image.network('https://example.com/pic.jpg'), )
Hero( tag: 'iconHero', child: Icon(Icons.star, size: 50), )
This app shows a small owl image on the first page. When you tap it, the image smoothly grows and moves to the second page. This is done by wrapping the image in a Hero widget with the same tag on both pages.
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Hero Animation Demo', home: const FirstPage(), ); } } class FirstPage extends StatelessWidget { const FirstPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('First Page')), body: Center( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const SecondPage()), ); }, child: Hero( tag: 'hero-image', child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg', width: 150, ), ), ), ), ), ); } } class SecondPage extends StatelessWidget { const SecondPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Second Page')), body: Center( child: Hero( tag: 'hero-image', child: Image.network( 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg', width: 300, ), ), ), ); } }
Make sure the tag is unique in the app and matches exactly on both widgets.
The Hero animation works best with images or shapes that look similar on both screens.
You can customize the animation by wrapping the Hero's child with other widgets like ClipRRect for rounded corners.
Hero animations create smooth transitions by moving a widget between screens.
Use the same tag on both widgets to link them.
They improve user experience by making navigation feel natural and connected.
Practice
Hero widget in Flutter?Solution
Step 1: Understand Hero widget role
The Hero widget is designed to animate a widget from one screen to another smoothly.Step 2: Identify correct purpose
It links widgets on different screens using the same tag to create a seamless transition.Final Answer:
To create smooth animations between two screens by linking widgets with the same tag -> Option AQuick Check:
Hero widget = smooth screen transition [OK]
- Confusing Hero with state management widgets
- Thinking Hero handles user input
- Assuming Hero fetches data
Solution
Step 1: Check Hero constructor syntax
The Hero widget requires named parameters:tagandchild.Step 2: Validate correct parameter order and types
Hero(tag: 'profilePic', child: Image.asset('pic.png')) uses named parameters correctly with a string tag and a child widget.Final Answer:
Hero(tag: 'profilePic', child: Image.asset('pic.png')) -> Option CQuick Check:
Hero uses named parameters tag and child [OK]
- Passing tag as positional argument
- Using unquoted tag string
- Swapping tag and child order without names
Screen A:
Hero(tag: 'logo', child: Image.asset('logo.png'))
Screen B:
Hero(tag: 'logo', child: Image.asset('logo_large.png'))Solution
Step 1: Understand Hero tag matching
Hero animations link widgets with the same tag, regardless of child widget differences.Step 2: Predict animation behavior
The image will animate smoothly from the smaller to the larger version because the tag matches.Final Answer:
The logo image will smoothly animate from Screen A to Screen B, changing size -> Option AQuick Check:
Matching tags animate widgets smoothly [OK]
- Assuming images must be identical for animation
- Thinking different children cause crashes
- Expecting no animation if child changes
Hero(tag: 'avatar', child: Container(color: Colors.blue)) // On next screen Hero(tag: 'avatar', child: Container(color: Colors.red))
Solution
Step 1: Check Hero child widget requirements
Hero animations require child widgets to have a defined size to animate properly.Step 2: Analyze Container usage
Container with only color but no size defaults to zero size, causing animation failure.Final Answer:
The Hero animation will fail because Container has no size -> Option BQuick Check:
Hero child needs size to animate [OK]
- Thinking tag mismatch causes error here
- Assuming Material widget is always required
- Ignoring size requirement of Hero child
Solution
Step 1: Use matching tags for Hero animation
Both Hero widgets must share the same tag to link the animation.Step 2: Handle shape differences smoothly
Wrap the small avatar in ClipOval for circle shape and the large image in ClipRRect with zero border radius for square shape to animate shape change smoothly.Final Answer:
Use the same tag on both Hero widgets; wrap the small avatar in a ClipOval and the large image in a ClipRRect with border radius zero -> Option DQuick Check:
Same tag + shape wrappers = smooth Hero animation [OK]
- Using different tags breaks animation
- Ignoring shape differences causes jumpy animation
- Assuming Material widget fixes shape issues
Ready to prove it?
Pass the test and this pattern moves unknown
