How to Use Hero Animation in Flutter for Smooth Transitions
Use the
Hero widget in Flutter by wrapping the shared widget on both source and destination screens with the same tag. Flutter automatically animates the transition between these widgets when navigating between routes.Syntax
The Hero widget requires a tag property that uniquely identifies the shared element. Wrap the widget you want to animate with Hero(tag: 'uniqueTag', child: YourWidget) on both the source and destination pages.
When you navigate between pages, Flutter matches the tag and animates the widget smoothly.
dart
Hero( tag: 'hero-tag', child: Image.asset('assets/picture.png'), )
Output
A widget wrapped in Hero with tag 'hero-tag' ready for animation between screens.
Example
This example shows two screens: a list with small images and a detail page with a larger image. Both images are wrapped in Hero widgets with the same tag. Tapping the image navigates to the detail page with a smooth hero animation.
dart
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( home: const ListPage(), ); } } class ListPage extends StatelessWidget { const ListPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Hero Animation Example')), body: Center( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const DetailPage()), ); }, child: Hero( tag: 'hero-image', child: Image.network( 'https://flutter.dev/assets/homepage/carousel/slide_1-bg-4e2fcef0f6b3b6f9a9f1a4a2a6a7f7a4e7f7a4e7f7a4e7f7a4e7f7a4e7f7a4e7.png', width: 100, ), ), ), ), ); } } class DetailPage extends StatelessWidget { const DetailPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Detail Page')), body: Center( child: Hero( tag: 'hero-image', child: Image.network( 'https://flutter.dev/assets/homepage/carousel/slide_1-bg-4e2fcef0f6b3b6f9a9f1a4a2a6a7f7a4e7f7a4e7f7a4e7f7a4e7f7a4e7f7a4e7.png', width: 300, ), ), ), ); } }
Output
App with a small image on the first screen that smoothly expands to a larger image on the detail screen when tapped.
Common Pitfalls
- Tag mismatch: The
tagmust be exactly the same on both widgets, or the animation won't work. - Different widget types: The widgets wrapped by
Heroshould be visually similar for a smooth animation. - Missing Hero on destination: Forgetting to wrap the destination widget with
Herocauses no animation. - Large widget rebuilds: Avoid rebuilding the hero widget unnecessarily during animation to prevent glitches.
dart
/* Wrong: Different tags */ Hero(tag: 'tag1', child: Image.asset('img1.png')) /* Right: Same tags */ Hero(tag: 'sharedTag', child: Image.asset('img1.png'))
Quick Reference
- Wrap shared widgets with
Heroand use the sametag. - Use
Navigator.pushto trigger the animation. - Ensure widgets look similar for smooth transition.
- Hero animations work best with images or icons.
Key Takeaways
Wrap widgets with
Hero using the same tag on both screens to enable animation.Use
Navigator.push to navigate and trigger the hero animation automatically.Ensure the hero widgets are visually similar for a smooth transition effect.
Avoid tag mismatches and missing Hero widgets on destination screens.
Hero animations are ideal for images and icons shared between screens.