From 7f79cced7ea4469148b1809c048285656ee2f705 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Sat, 4 Feb 2017 09:34:14 -0800 Subject: [PATCH] Give more control to SliverChildDelegate (#7885) This patch moves the resonsibility for wrapping repaint boundaries around children to SliverChildDelegate, which means delegates can choose whether or no to use repaint boundaries. Also introduce SliverChildBuilderDelegate to make it easier to use the builder pattern with sliver lists. This functionality will be used by date picker, which wants to use a SliverGrid but doesn't need a repaint boundary around every day in a month grid. --- packages/flutter/lib/src/widgets/sliver.dart | 36 ++++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/flutter/lib/src/widgets/sliver.dart b/packages/flutter/lib/src/widgets/sliver.dart index 5cc0a0ab246..d562e6a107e 100644 --- a/packages/flutter/lib/src/widgets/sliver.dart +++ b/packages/flutter/lib/src/widgets/sliver.dart @@ -41,6 +41,31 @@ abstract class SliverChildDelegate { bool shouldRebuild(@checked SliverChildDelegate oldDelegate); } +class SliverChildBuilderDelegate extends SliverChildDelegate { + const SliverChildBuilderDelegate(this.builder, { this.childCount }); + + final IndexedWidgetBuilder builder; + + final int childCount; + + @override + Widget build(BuildContext context, int index) { + assert(builder != null); + if (index < 0 || (childCount != null && index >= childCount)) + return null; + final Widget child = builder(context, index); + if (child == null) + return null; + return new RepaintBoundary.wrap(child, index); + } + + @override + int get estimatedChildCount => childCount; + + @override + bool shouldRebuild(@checked SliverChildListDelegate oldDelegate) => true; +} + // /// // /// In general building all the widgets in advance is not efficient. It is // /// better to create a delegate that builds them on demand by subclassing @@ -63,7 +88,9 @@ class SliverChildListDelegate extends SliverChildDelegate { assert(children != null); if (index < 0 || index >= children.length) return null; - return children[index]; + final Widget child = children[index]; + assert(child != null); + return new RepaintBoundary.wrap(child, index); } @override @@ -253,12 +280,7 @@ class SliverMultiBoxAdaptorElement extends RenderObjectElement implements Render } Widget _build(int index) { - return _childWidgets.putIfAbsent(index, () { - Widget child = widget.delegate.build(this, index); - if (child == null) - return null; - return new RepaintBoundary.wrap(child, index); - }); + return _childWidgets.putIfAbsent(index, () => widget.delegate.build(this, index)); } @override