From b5ed355b93d2a83a8080e86918046bbef7b15922 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 14 Jan 2016 10:19:05 -0800 Subject: [PATCH] Stocks has both tabs reified in the wiget tree We were recomputing which widgets to show only when we were on the other side of the repaint boundaries. That doesn't work well for pageable lists because we come to rest exactly on a repaint boundary, which means we don't cull the other page. After this patch, we recompute the set of widgets using an edge-trigger when we hit the boundary. That's better than using a level-trigger so that we don't continuously recompute the set of widget as we sit at the boundary. --- .../lib/src/widgets/pageable_list.dart | 4 +-- .../lib/src/widgets/scrollable_grid.dart | 4 +-- .../lib/src/widgets/scrollable_list.dart | 4 +-- .../lib/src/widgets/virtual_viewport.dart | 26 ++++++++++++++----- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/flutter/lib/src/widgets/pageable_list.dart b/packages/flutter/lib/src/widgets/pageable_list.dart index 144da0388e0..1b627df9fe5 100644 --- a/packages/flutter/lib/src/widgets/pageable_list.dart +++ b/packages/flutter/lib/src/widgets/pageable_list.dart @@ -225,10 +225,10 @@ class _PageViewportElement extends VirtualViewportElement { return -(widget.startOffset - startOffsetBase) * _containerExtent; } - void updateRenderObject() { + void updateRenderObject(PageViewport oldWidget) { renderObject.scrollDirection = widget.scrollDirection; renderObject.overlayPainter = widget.overlayPainter; - super.updateRenderObject(); + super.updateRenderObject(oldWidget); } double _containerExtent; diff --git a/packages/flutter/lib/src/widgets/scrollable_grid.dart b/packages/flutter/lib/src/widgets/scrollable_grid.dart index 5e10aee624f..740c6e60c5e 100644 --- a/packages/flutter/lib/src/widgets/scrollable_grid.dart +++ b/packages/flutter/lib/src/widgets/scrollable_grid.dart @@ -122,9 +122,9 @@ class _GridViewportElement extends VirtualViewportElement { double get startOffsetLimit =>_startOffsetLimit; double _startOffsetLimit; - void updateRenderObject() { + void updateRenderObject(GridViewport oldWidget) { renderObject.delegate = widget.delegate; - super.updateRenderObject(); + super.updateRenderObject(oldWidget); } double _contentExtent; diff --git a/packages/flutter/lib/src/widgets/scrollable_list.dart b/packages/flutter/lib/src/widgets/scrollable_list.dart index 0c4ed01ec5a..ec00da93277 100644 --- a/packages/flutter/lib/src/widgets/scrollable_list.dart +++ b/packages/flutter/lib/src/widgets/scrollable_list.dart @@ -135,12 +135,12 @@ class _ListViewportElement extends VirtualViewportElement { double get startOffsetLimit =>_startOffsetLimit; double _startOffsetLimit; - void updateRenderObject() { + void updateRenderObject(ListViewport oldWidget) { renderObject.scrollDirection = widget.scrollDirection; renderObject.itemExtent = widget.itemExtent; renderObject.padding = widget.padding; renderObject.overlayPainter = widget.overlayPainter; - super.updateRenderObject(); + super.updateRenderObject(oldWidget); } double _contentExtent; diff --git a/packages/flutter/lib/src/widgets/virtual_viewport.dart b/packages/flutter/lib/src/widgets/virtual_viewport.dart index bd28d0d0157..b43e89df180 100644 --- a/packages/flutter/lib/src/widgets/virtual_viewport.dart +++ b/packages/flutter/lib/src/widgets/virtual_viewport.dart @@ -43,7 +43,7 @@ abstract class VirtualViewportElement extends RenderO _iterator = null; _widgets = []; renderObject.callback = layout; - updateRenderObject(); + updateRenderObject(null); } void unmount() { @@ -56,8 +56,9 @@ abstract class VirtualViewportElement extends RenderO _iterator = null; _widgets = []; } + T oldWidget = widget; super.update(newWidget); - updateRenderObject(); + updateRenderObject(oldWidget); if (!renderObject.needsLayout) _materializeChildren(); } @@ -73,7 +74,7 @@ abstract class VirtualViewportElement extends RenderO } } - void updateRenderObject() { + void updateRenderObject(T oldWidget) { renderObject.virtualChildCount = widget.children.length; if (startOffsetBase != null) { @@ -82,9 +83,22 @@ abstract class VirtualViewportElement extends RenderO // If we don't already need layout, we need to request a layout if the // viewport has shifted to expose new children. if (!renderObject.needsLayout) { - if (startOffsetBase != null && widget.startOffset < startOffsetBase) - renderObject.markNeedsLayout(); - else if (startOffsetLimit != null && widget.startOffset > startOffsetLimit) + bool shouldLayout = false; + if (startOffsetBase != null) { + if (widget.startOffset < startOffsetBase) + shouldLayout = true; + else if (widget.startOffset == startOffsetBase && oldWidget?.startOffset != startOffsetBase) + shouldLayout = true; + } + + if (startOffsetLimit != null) { + if (widget.startOffset > startOffsetLimit) + shouldLayout = true; + else if (widget.startOffset == startOffsetLimit && oldWidget?.startOffset != startOffsetLimit) + shouldLayout = true; + } + + if (shouldLayout) renderObject.markNeedsLayout(); } }