Animate a widget across screens
It’s often helpful to guide users through an app as they navigate from screen to screen. A common technique to lead users through an app is to animate a widget from one screen to the next. This creates a visual anchor connecting the two screens.
Use the
Hero
widget
to animate a widget from one screen to the next.
This recipe uses the following steps:
- Create two screens showing the same image.
- Add a
Hero
widget to the first screen. - Add a
Hero
widget to the second screen.
1. Create two screens showing the same image
In this example, display the same image on both screens. Animate the image from the first screen to the second screen when the user taps the image. For now, create the visual structure; handle animations in the next steps.
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
body: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return DetailScreen();
}));
},
child: Image.network(
'https://picsum.photos/250?image=9',
),
),
);
}
}
class DetailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Image.network(
'https://picsum.photos/250?image=9',
),
),
),
);
}
}
Hero
widget to the first screen
2. Add a To connect the two screens together with an animation, wrap
the Image
widget on both screens in a Hero
widget.
The Hero
widget requires two arguments:
- `tag`
- An object that identifies the `Hero`. It must be the same on both screens.
- `child`
- The widget to animate across screens.
Hero(
tag: 'imageHero',
child: Image.network(
'https://picsum.photos/250?image=9',
),
);
Hero
widget to the second screen
3. Add a To complete the connection with the first screen,
wrap the Image
on the second screen with a Hero
widget that has the same tag
as the Hero
in the first screen.
After applying the Hero
widget to the second screen,
the animation between screens just works.
Hero(
tag: 'imageHero',
child: Image.network(
'https://picsum.photos/250?image=9',
),
);
Complete example
import 'package:flutter/material.dart';
void main() => runApp(HeroApp());
class HeroApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Transition Demo',
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
body: GestureDetector(
child: Hero(
tag: 'imageHero',
child: Image.network(
'https://picsum.photos/250?image=9',
),
),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return DetailScreen();
}));
},
),
);
}
}
class DetailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
child: Center(
child: Hero(
tag: 'imageHero',
child: Image.network(
'https://picsum.photos/250?image=9',
),
),
),
onTap: () {
Navigator.pop(context);
},
),
);
}
}