From 95fbd819fa618f2f7e636c18d2dc62069acb9075 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Fri, 16 Mar 2018 10:37:01 -0700 Subject: [PATCH] Place the transform and its children within the RenderFlow's opacity layer (#15543) Fixes https://github.com/flutter/flutter/issues/15037 --- packages/flutter/lib/src/rendering/flow.dart | 2 +- packages/flutter/test/widgets/flow_test.dart | 36 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/rendering/flow.dart b/packages/flutter/lib/src/rendering/flow.dart index 6cd66d57929..04f147f0acf 100644 --- a/packages/flutter/lib/src/rendering/flow.dart +++ b/packages/flutter/lib/src/rendering/flow.dart @@ -342,7 +342,7 @@ class RenderFlow extends RenderBox _paintingContext.pushTransform(needsCompositing, _paintingOffset, transform, painter); } else { _paintingContext.pushOpacity(_paintingOffset, _getAlphaFromOpacity(opacity), (PaintingContext context, Offset offset) { - _paintingContext.pushTransform(needsCompositing, offset, transform, painter); + context.pushTransform(needsCompositing, offset, transform, painter); }); } } diff --git a/packages/flutter/test/widgets/flow_test.dart b/packages/flutter/test/widgets/flow_test.dart index 18991e8835e..83c35606f82 100644 --- a/packages/flutter/test/widgets/flow_test.dart +++ b/packages/flutter/test/widgets/flow_test.dart @@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter/rendering.dart'; class TestFlowDelegate extends FlowDelegate { TestFlowDelegate({this.startOffset}) : super(repaint: startOffset); @@ -28,6 +29,22 @@ class TestFlowDelegate extends FlowDelegate { bool shouldRepaint(TestFlowDelegate oldDelegate) => startOffset == oldDelegate.startOffset; } +class OpacityFlowDelegate extends FlowDelegate { + OpacityFlowDelegate(this.opacity); + + double opacity; + + @override + void paintChildren(FlowPaintingContext context) { + for (int i = 0; i < context.childCount; ++i) { + context.paintChild(i, opacity: opacity); + } + } + + @override + bool shouldRepaint(OpacityFlowDelegate oldDelegate) => opacity != oldDelegate.opacity; +} + void main() { testWidgets('Flow control test', (WidgetTester tester) async { final AnimationController startOffset = new AnimationController.unbounded( @@ -82,4 +99,23 @@ void main() { await tester.tapAt(const Offset(20.0, 90.0)); expect(log, equals([0])); }); + + testWidgets('Flow opacity layer', (WidgetTester tester) async { + const double opacity = 0.2; + await tester.pumpWidget( + new Flow( + delegate: new OpacityFlowDelegate(opacity), + children: [ + new Container(width: 100.0, height: 100.0), + ] + ) + ); + ContainerLayer layer = RendererBinding.instance.renderView.debugLayer; + while (layer != null && !(layer is OpacityLayer)) + layer = layer.firstChild; + expect(layer, const isInstanceOf()); + final OpacityLayer opacityLayer = layer; + expect(opacityLayer.alpha, equals(opacity * 255)); + expect(layer.firstChild, const isInstanceOf()); + }); }