Hero Animations
A Hero animation in Flutter enables a smooth, visually appealing transition for a widget that appears on two different screens. This technique is especially useful when you want to create a sense of continuity for shared elements, such as images, icons, or cards, as users navigate between routes.
By animating the shared element from one screen to another, you help users maintain context and create a more polished, professional experience. You should use Hero animations when you want a specific widget to visually fly from one page to the next, reinforcing the connection between screens and making navigation feel seamless.
main.dart
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869import 'package:flutter/material.dart'; void main() => runApp(HeroDemoApp()); class HeroDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Hero Animation Demo', home: FirstScreen(), ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (_) => SecondScreen()), ); }, child: Hero( tag: 'demo-image', child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.network( 'https://flutter.dev/images/catalog-widget-placeholder.png', width: 150, height: 150, ), ), ), ), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: Hero( tag: 'demo-image', child: ClipRRect( borderRadius: BorderRadius.circular(32), child: Image.network( 'https://flutter.dev/images/catalog-widget-placeholder.png', width: 300, height: 300, ), ), ), ), ); } }
The Hero widget's tag property is essential for linking shared elements across different routes. When you wrap a widget in a Hero and assign it a unique tag, Flutter matches all Hero widgets with the same tag on the source and destination screens. During navigation, Flutter animates the widget from its position on the first screen to its position on the second screen, as shown in the example above. The tag must be unique within the navigation context to avoid conflicts. If the tags match, the transition animation is triggered, creating the seamless effect that connects the two screens visually. Without matching tags, Flutter cannot identify which widgets to animate between routes, and the Hero animation will not occur.
Thanks for your feedback!
Ask AI
Ask AI
Ask anything or try one of the suggested questions to begin our chat
Can you explain how to implement a Hero animation in Flutter?
What happens if two Hero widgets have the same tag on the same screen?
Are there any best practices for choosing Hero tags?
Awesome!
Completion rate improved to 9.09
Hero Animations
Swipe to show menu
A Hero animation in Flutter enables a smooth, visually appealing transition for a widget that appears on two different screens. This technique is especially useful when you want to create a sense of continuity for shared elements, such as images, icons, or cards, as users navigate between routes.
By animating the shared element from one screen to another, you help users maintain context and create a more polished, professional experience. You should use Hero animations when you want a specific widget to visually fly from one page to the next, reinforcing the connection between screens and making navigation feel seamless.
main.dart
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869import 'package:flutter/material.dart'; void main() => runApp(HeroDemoApp()); class HeroDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Hero Animation Demo', home: FirstScreen(), ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (_) => SecondScreen()), ); }, child: Hero( tag: 'demo-image', child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.network( 'https://flutter.dev/images/catalog-widget-placeholder.png', width: 150, height: 150, ), ), ), ), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: Hero( tag: 'demo-image', child: ClipRRect( borderRadius: BorderRadius.circular(32), child: Image.network( 'https://flutter.dev/images/catalog-widget-placeholder.png', width: 300, height: 300, ), ), ), ), ); } }
The Hero widget's tag property is essential for linking shared elements across different routes. When you wrap a widget in a Hero and assign it a unique tag, Flutter matches all Hero widgets with the same tag on the source and destination screens. During navigation, Flutter animates the widget from its position on the first screen to its position on the second screen, as shown in the example above. The tag must be unique within the navigation context to avoid conflicts. If the tags match, the transition animation is triggered, creating the seamless effect that connects the two screens visually. Without matching tags, Flutter cannot identify which widgets to animate between routes, and the Hero animation will not occur.
Thanks for your feedback!