Improve compositing strategy for Shrine (#5014)
This patch includes a number of improvements:
* Material page routes now put a repaint boundary inside their transition so
they don't repaint during the transition.
* Heroes that are on a quest now get a repaint boundary so we repaint them
individually.
* I've hoisted the transparent material for the product items up in the widget
tree, which doesn't affect performance but makes the ink splashes reach the
edge of the product cards.
* I've changed the repaint rainbow visualization to make it easier to see
what's going on.
diff --git a/examples/flutter_gallery/lib/demo/shrine/shrine_home.dart b/examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
index 901a29a..13158b3 100644
--- a/examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
+++ b/examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
@@ -258,37 +258,37 @@
@override
Widget build(BuildContext context) {
return new Card(
- child: new Column(
+ child: new Stack(
children: <Widget>[
- new Align(
- alignment: FractionalOffset.centerRight,
- child: new ProductPriceItem(product: product)
- ),
- new Container(
- width: 144.0,
- height: 144.0,
- padding: const EdgeInsets.symmetric(horizontal: 8.0),
- child: new Stack(
- children: <Widget>[
- new Hero(
- tag: productHeroTag,
- key: new ObjectKey(product),
- child: new Image(
- image: new AssetImage(product.imageAsset),
- fit: ImageFit.contain
+ new Column(
+ children: <Widget>[
+ new Align(
+ alignment: FractionalOffset.centerRight,
+ child: new ProductPriceItem(product: product)
+ ),
+ new Container(
+ width: 144.0,
+ height: 144.0,
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: new Hero(
+ tag: productHeroTag,
+ key: new ObjectKey(product),
+ child: new Image(
+ image: new AssetImage(product.imageAsset),
+ fit: ImageFit.contain
+ )
)
),
- new Material(
- color: Theme.of(context).canvasColor.withAlpha(0x00),
- child: new InkWell(onTap: onPressed)
- ),
- ]
- )
+ new Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: new VendorItem(vendor: product.vendor)
+ )
+ ]
),
- new Padding(
- padding: const EdgeInsets.symmetric(horizontal: 8.0),
- child: new VendorItem(vendor: product.vendor)
- )
+ new Material(
+ type: MaterialType.transparency,
+ child: new InkWell(onTap: onPressed)
+ ),
]
)
);
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index 5dcd985..7b2a45d 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -173,8 +173,13 @@
if (!_isRecording)
return;
assert(() {
- if (debugRepaintRainbowEnabled)
- canvas.drawRect(_paintBounds, new Paint()..color = debugCurrentRepaintColor.toColor());
+ if (debugRepaintRainbowEnabled) {
+ Paint paint = new Paint()
+ ..style = PaintingStyle.stroke
+ ..strokeWidth = 6.0
+ ..color = debugCurrentRepaintColor.toColor();
+ canvas.drawRect(_paintBounds.deflate(3.0), paint);
+ }
if (debugPaintLayerBordersEnabled) {
Paint paint = new Paint()
..style = PaintingStyle.stroke
diff --git a/packages/flutter/lib/src/widgets/heroes.dart b/packages/flutter/lib/src/widgets/heroes.dart
index a64c7f8..4a86eed 100644
--- a/packages/flutter/lib/src/widgets/heroes.dart
+++ b/packages/flutter/lib/src/widgets/heroes.dart
@@ -272,7 +272,7 @@
size: animationArea.size,
child: new RotationTransition(
turns: currentTurns.animate(animation),
- child: new KeyedSubtree(
+ child: new RepaintBoundary(
key: key,
child: child
)
diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart
index d73f4da..c5bb5c2 100644
--- a/packages/flutter/lib/src/widgets/routes.dart
+++ b/packages/flutter/lib/src/widgets/routes.dart
@@ -426,15 +426,14 @@
context,
config.route.animation,
config.route.forwardAnimation,
- contents
+ new RepaintBoundary(child: contents)
)
);
}
- contents = new Focus(
+ return new Focus(
key: config.route.focusKey,
- child: new RepaintBoundary(child: contents)
+ child: contents
);
- return contents;
}
}