Commit 4086e7a3 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Improve performance of Pesto hero animation (#5182)

Previously we were resizing a paragraph of text during the animation. Now we
animate the text and the image separately. Also, add a default hero tag for
FloatingActionButton so that it animates as part of the hero transition as
well.
parent 82b7fc0d
...@@ -232,13 +232,14 @@ class _RecipeCard extends StatelessWidget { ...@@ -232,13 +232,14 @@ class _RecipeCard extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new GestureDetector( return new GestureDetector(
onTap: onTap, onTap: onTap,
child: new Hero(
tag: recipe.imagePath,
child: new Card( child: new Card(
child: new Column( child: new Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
new Image.asset(recipe.imagePath, fit: ImageFit.contain), new Hero(
tag: recipe.imagePath,
child: new Image.asset(recipe.imagePath, fit: ImageFit.contain)
),
new Flexible( new Flexible(
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
...@@ -264,7 +265,6 @@ class _RecipeCard extends StatelessWidget { ...@@ -264,7 +265,6 @@ class _RecipeCard extends StatelessWidget {
] ]
) )
) )
)
); );
} }
} }
...@@ -327,21 +327,23 @@ class _RecipePageState extends State<_RecipePage> { ...@@ -327,21 +327,23 @@ class _RecipePageState extends State<_RecipePage> {
Size screenSize = MediaQuery.of(context).size; Size screenSize = MediaQuery.of(context).size;
bool fullWidth = (screenSize.width < _kRecipePageMaxWidth); bool fullWidth = (screenSize.width < _kRecipePageMaxWidth);
const double fabHalfSize = 28.0; // TODO(mpcomplete): needs to adapt to screen size const double fabHalfSize = 28.0; // TODO(mpcomplete): needs to adapt to screen size
return new Hero( return new Stack(
children: <Widget>[
new Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: new Hero(
tag: config.recipe.imagePath, tag: config.recipe.imagePath,
child: new Container( child: new Image.asset(
decoration: new BoxDecoration( config.recipe.imagePath,
backgroundColor: Theme.of(context).canvasColor,
backgroundImage: new BackgroundImage(
image: new AssetImage(config.recipe.imagePath),
alignment: FractionalOffset.topCenter,
fit: fullWidth ? ImageFit.fitWidth : ImageFit.cover fit: fullWidth ? ImageFit.fitWidth : ImageFit.cover
) )
)
), ),
align: FractionalOffset.bottomCenter, new ScrollableViewport(
child: new Block( child: new RepaintBoundary(
children: <Widget>[ child: new Padding(
new Padding(
padding: new EdgeInsets.only(top: _getAppBarHeight(context)), padding: new EdgeInsets.only(top: _getAppBarHeight(context)),
child: new Stack( child: new Stack(
children: <Widget>[ children: <Widget>[
...@@ -362,9 +364,9 @@ class _RecipePageState extends State<_RecipePage> { ...@@ -362,9 +364,9 @@ class _RecipePageState extends State<_RecipePage> {
] ]
) )
) )
]
) )
) )
]
); );
} }
......
...@@ -17,6 +17,7 @@ import 'tooltip.dart'; ...@@ -17,6 +17,7 @@ import 'tooltip.dart';
// http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing // http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
const double _kSize = 56.0; const double _kSize = 56.0;
const double _kSizeMini = 40.0; const double _kSizeMini = 40.0;
final Object _kDefaultHeroTag = new Object();
/// A material design floating action button. /// A material design floating action button.
/// ///
...@@ -46,6 +47,7 @@ class FloatingActionButton extends StatefulWidget { ...@@ -46,6 +47,7 @@ class FloatingActionButton extends StatefulWidget {
@required this.child, @required this.child,
this.tooltip, this.tooltip,
this.backgroundColor, this.backgroundColor,
this.heroTag,
this.elevation: 6, this.elevation: 6,
this.highlightElevation: 12, this.highlightElevation: 12,
@required this.onPressed, @required this.onPressed,
...@@ -66,6 +68,11 @@ class FloatingActionButton extends StatefulWidget { ...@@ -66,6 +68,11 @@ class FloatingActionButton extends StatefulWidget {
/// Defaults to the accent color of the current theme. /// Defaults to the accent color of the current theme.
final Color backgroundColor; final Color backgroundColor;
/// The tag to apply to the button's [Hero] widget.
///
/// Defaults to a tag that matches other floating action buttons.
final Object heroTag;
/// The callback that is called when the button is tapped or otherwise activated. /// The callback that is called when the button is tapped or otherwise activated.
/// ///
/// If this is set to null, the button will be disabled. /// If this is set to null, the button will be disabled.
...@@ -124,7 +131,9 @@ class _FloatingActionButtonState extends State<FloatingActionButton> { ...@@ -124,7 +131,9 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
); );
} }
return new Material( return new Hero(
tag: config.heroTag ?? _kDefaultHeroTag,
child: new Material(
color: materialColor, color: materialColor,
type: MaterialType.circle, type: MaterialType.circle,
elevation: _highlight ? config.highlightElevation : config.elevation, elevation: _highlight ? config.highlightElevation : config.elevation,
...@@ -137,6 +146,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> { ...@@ -137,6 +146,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
child: result child: result
) )
) )
)
); );
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment