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,37 +232,37 @@ class _RecipeCard extends StatelessWidget { ...@@ -232,37 +232,37 @@ 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( child: new Card(
tag: recipe.imagePath, child: new Column(
child: new Card( crossAxisAlignment: CrossAxisAlignment.start,
child: new Column( children: <Widget>[
crossAxisAlignment: CrossAxisAlignment.start, new Hero(
children: <Widget>[ tag: recipe.imagePath,
new Image.asset(recipe.imagePath, fit: ImageFit.contain), child: new Image.asset(recipe.imagePath, fit: ImageFit.contain)
new Flexible( ),
child: new Row( new Flexible(
children: <Widget>[ child: new Row(
new Padding( children: <Widget>[
padding: const EdgeInsets.all(16.0), new Padding(
child: new Image.asset( padding: const EdgeInsets.all(16.0),
recipe.ingredientsImagePath, child: new Image.asset(
width: 48.0, recipe.ingredientsImagePath,
height: 48.0 width: 48.0,
) height: 48.0
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(recipe.name, style: titleStyle),
new Text(recipe.author, style: authorStyle),
]
) )
] ),
) new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(recipe.name, style: titleStyle),
new Text(recipe.author, style: authorStyle),
]
)
]
) )
] )
) ]
) )
) )
); );
...@@ -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(
tag: config.recipe.imagePath, children: <Widget>[
child: new Container( new Positioned(
decoration: new BoxDecoration( top: 0.0,
backgroundColor: Theme.of(context).canvasColor, left: 0.0,
backgroundImage: new BackgroundImage( right: 0.0,
image: new AssetImage(config.recipe.imagePath), child: new Hero(
alignment: FractionalOffset.topCenter, tag: config.recipe.imagePath,
fit: fullWidth ? ImageFit.fitWidth : ImageFit.cover child: new Image.asset(
config.recipe.imagePath,
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,17 +131,20 @@ class _FloatingActionButtonState extends State<FloatingActionButton> { ...@@ -124,17 +131,20 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
); );
} }
return new Material( return new Hero(
color: materialColor, tag: config.heroTag ?? _kDefaultHeroTag,
type: MaterialType.circle, child: new Material(
elevation: _highlight ? config.highlightElevation : config.elevation, color: materialColor,
child: new Container( type: MaterialType.circle,
width: config.mini ? _kSizeMini : _kSize, elevation: _highlight ? config.highlightElevation : config.elevation,
height: config.mini ? _kSizeMini : _kSize, child: new Container(
child: new InkWell( width: config.mini ? _kSizeMini : _kSize,
onTap: config.onPressed, height: config.mini ? _kSizeMini : _kSize,
onHighlightChanged: _handleHighlightChanged, child: new InkWell(
child: result onTap: config.onPressed,
onHighlightChanged: _handleHighlightChanged,
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