Commit c40b92b9 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Material should unconditionally repaint on LayoutChangedNotification (#8107)

When a ListView scrolls, it generates a LayoutChangedNotification, which was
causing Material to repaint unconditionally. That's not necessary if there are
no ink effects that need to be moved. This patch skips the repaint in that
case.

Fixes #7937
parent 39f7d58b
......@@ -216,7 +216,8 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
}
contents = new NotificationListener<LayoutChangedNotification>(
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;
......
......@@ -13,12 +13,86 @@ class NotifyMaterial extends StatelessWidget {
}
}
class PaintRecorder extends CustomPainter {
PaintRecorder(this.log);
List<Size> 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<Size> log = <Size>[];
await tester.pumpWidget(
new Column(
children: <Widget>[
new SizedBox(
width: 150.0,
height: 150.0,
child: new CustomPaint(
painter: new PaintRecorder(log),
),
),
new Expanded(
child: new Material(
child: new Column(
children: <Widget>[
new Expanded(
child: new ListView(
children: <Widget>[
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(<Size>[
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);
});
}
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