diff --git a/packages/flutter/lib/src/material/material.dart b/packages/flutter/lib/src/material/material.dart index b0eb8e29a0..e25d887ae4 100644 --- a/packages/flutter/lib/src/material/material.dart +++ b/packages/flutter/lib/src/material/material.dart @@ -216,7 +216,8 @@ class _MaterialState extends State with TickerProviderStateMixin { } contents = new NotificationListener( onNotification: (LayoutChangedNotification notification) { - _inkFeatureRenderer.currentContext.findRenderObject().markNeedsPaint(); + _RenderInkFeatures renderer = _inkFeatureRenderer.currentContext.findRenderObject(); + renderer._didChangeLayout(); return true; }, child: new _InkFeatures( @@ -292,6 +293,11 @@ class _RenderInkFeatures extends RenderProxyBox implements MaterialInkController markNeedsPaint(); } + void _didChangeLayout() { + if (_inkFeatures.isNotEmpty) + markNeedsPaint(); + } + @override bool hitTestSelf(Point position) => true; diff --git a/packages/flutter/test/material/material_test.dart b/packages/flutter/test/material/material_test.dart index 2633a5e5b2..3ef8fed31c 100644 --- a/packages/flutter/test/material/material_test.dart +++ b/packages/flutter/test/material/material_test.dart @@ -13,12 +13,86 @@ class NotifyMaterial extends StatelessWidget { } } +class PaintRecorder extends CustomPainter { + PaintRecorder(this.log); + + List log; + + @override + void paint(Canvas canvas, Size size) { + log.add(size); + final Paint paint = new Paint()..color = const Color(0xFF0000FF); + canvas.drawRect(Point.origin & size, paint); + } + + @override + bool shouldRepaint(PaintRecorder oldDelegate) => false; +} + void main() { testWidgets('LayoutChangedNotificaion test', (WidgetTester tester) async { await tester.pumpWidget( new Material( - child: new NotifyMaterial() - ) + child: new NotifyMaterial(), + ), ); }); + + testWidgets('ListView scroll does not repaint', (WidgetTester tester) async { + List log = []; + + await tester.pumpWidget( + new Column( + children: [ + new SizedBox( + width: 150.0, + height: 150.0, + child: new CustomPaint( + painter: new PaintRecorder(log), + ), + ), + new Expanded( + child: new Material( + child: new Column( + children: [ + new Expanded( + child: new ListView( + children: [ + new Container( + height: 2000.0, + decoration: const BoxDecoration( + backgroundColor: const Color(0xFF00FF00), + ), + ), + ], + ), + ), + new SizedBox( + width: 100.0, + height: 100.0, + child: new CustomPaint( + painter: new PaintRecorder(log), + ), + ), + ], + ), + ), + ), + ], + ), + ); + + // We paint twice because we have two CustomPaint widgets in the tree above + // to test repainting both inside and outside the Material widget. + expect(log, equals([ + const Size(150.0, 150.0), + const Size(100.0, 100.0), + ])); + log.clear(); + + await tester.scroll(find.byType(ListView), const Offset(0.0, -300.0)); + await tester.pump(); + + expect(log, isEmpty); + }); }