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 144da0388e..1b627df9fe 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 5e10aee624..740c6e60c5 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 0c4ed01ec5..ec00da9327 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 bd28d0d015..b43e89df18 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(); } }