Shared Element transitions are native in Android, but with Flutter you can do the same UI transition with Flutter as well.
Watch Video Tutorial
Hero Widgets
Shared element transitions can be achieved in Flutter with the help of Hero Widgets.
Here I have two Screens, one is called ScreenOne and other DetailsScreen.
ScreeOne has a small image and a button below it. On Clicking the button, we will open the Details screen with the Shared Element transition. You can see the demo if you watch the above tutorial.
ScreenOne
import 'package:flutter/material.dart'; import 'package:flutter_demo1/transition/details.dart'; class ScreenOne extends StatefulWidget { ScreenOne() : super(); final String title = "Screen One"; @override _ScreenOneState createState() => _ScreenOneState(); } class _ScreenOneState extends State<ScreenOne> { goToDetails(BuildContext context) { Navigator.push( context, new MaterialPageRoute( fullscreenDialog: true, builder: (BuildContext context) => new DetailsScreen()), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Container( color: Colors.green, padding: EdgeInsets.all(30.0), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Hero( tag: "image1", child: ClipOval( child: Image.asset( "images/flutter.jpg", width: 200, height: 200, ), ), ), SizedBox( height: 30.0, ), OutlineButton( child: Text( "Show Full Image", style: TextStyle(color: Colors.white), ), padding: EdgeInsets.all(20.0), onPressed: () { goToDetails(context); }, ) ], ), ), ); } }
The ‘goToDetails()‘ function will open the DetailsScreen.
Look at the image in the above code, We are wrapping it in a ClipOval to give it an Oval look. And wrap the Clip Oval with the Hero Widget. Don’t forget to the give the tag for Hero Widget. Here I have given as “image1”. I will be giving the same tag for the image which I want to transition to, that will be in the DetailsScreen. Let’ see what the DetailsScreen will look like.
DetailsScreen
import 'package:flutter/material.dart'; class DetailsScreen extends StatefulWidget { DetailsScreen() : super(); final String title = "Details"; @override DetailsScreenState createState() => DetailsScreenState(); } class DetailsScreenState extends State<DetailsScreen> { @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: EdgeInsets.all(40.0), child: Stack( alignment: Alignment.bottomCenter, children: <Widget>[ Hero( tag: "image1", child: Image.asset( "images/flutter.jpg", width: 800, height: 800, ), ), SizedBox( height: 30.0, ), OutlineButton( child: Icon(Icons.close), padding: EdgeInsets.all(20.0), onPressed: () { Navigator.pop(context); }, ) ], ), )); } }
Take a look at the code below in the DetailsScreen
Hero( tag: "image1", child: Image.asset( "images/flutter.jpg", width: 800, height: 800, ), ), ...
Here I have the same tag as in the ScreenOne image. When we tap the button in the ScreenOne, it will open the DetailsScreen with the transition from Smaller image to Bigger image in the DetailsScreen.
Note: if you don’t give tag to the Hero Widget, your build will fail. Also make sure you have the same tag for both images which you want the shared transition.
All good.
Thanks for reading.
Please leave your valuable comments below.