Chromium Code Reviews| Index: sky/sdk/lib/widgets/block_viewport.dart |
| diff --git a/sky/sdk/lib/widgets/block_viewport.dart b/sky/sdk/lib/widgets/block_viewport.dart |
| index 8aa0f0c3756dd5379739ca19977e2cf0cc7417af..98f5c6a338d66523032bc7f30eb04e35803d2817 100644 |
| --- a/sky/sdk/lib/widgets/block_viewport.dart |
| +++ b/sky/sdk/lib/widgets/block_viewport.dart |
| @@ -2,6 +2,8 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +import 'dart:collection'; |
| + |
| import '../rendering/block.dart'; |
| import '../rendering/box.dart'; |
| import '../rendering/object.dart'; |
| @@ -10,6 +12,13 @@ import 'widget.dart'; |
| // return null if index is greater than index of last entry |
| typedef Widget IndexedBuilder(int index); |
| +typedef void LayoutChangedCallback( |
| + int firstVisibleChildIndex, |
| + int visibleChildCount, |
| + UnmodifiableListView<double> childOffsets, |
| + bool didReachLastChild |
| +); |
| + |
| class _Key { |
| const _Key(this.type, this.key); |
| factory _Key.fromWidget(Widget widget) => new _Key(widget.runtimeType, widget.key); |
| @@ -20,12 +29,13 @@ class _Key { |
| } |
| class BlockViewport extends RenderObjectWrapper { |
| - BlockViewport({ this.builder, this.startOffset, this.token, String key }) |
| + BlockViewport({ this.builder, this.startOffset, this.token, this.onLayoutChanged, String key }) |
| : super(key: key); |
| IndexedBuilder builder; |
| double startOffset; |
| Object token; |
| + LayoutChangedCallback onLayoutChanged; |
| RenderBlockViewport get root => super.root; |
| RenderBlockViewport createNode() => new RenderBlockViewport(); |
| @@ -83,6 +93,7 @@ class BlockViewport extends RenderObjectWrapper { |
| List<double> _offsets = <double>[0.0]; |
| int _currentStartIndex = 0; |
| int _currentChildCount = 0; |
| + bool _didReachLastChild = false; |
| int _findIndexForOffsetBeforeOrAt(double offset) { |
| int left = 0; |
| @@ -113,6 +124,7 @@ class BlockViewport extends RenderObjectWrapper { |
| builder = newNode.builder; |
| token = newNode.token; |
| _offsets = <double>[0.0]; |
| + _didReachLastChild = false; |
| } |
| return true; |
| } |
| @@ -196,6 +208,7 @@ class BlockViewport extends RenderObjectWrapper { |
| haveChildren = true; |
| } else { |
| haveChildren = false; |
| + _didReachLastChild = true; |
| } |
| } |
| } else { |
| @@ -207,8 +220,10 @@ class BlockViewport extends RenderObjectWrapper { |
| // list is complete (and thus we are overscrolled). |
| while (true) { |
| Widget widget = _getWidget(startIndex, innerConstraints); |
| - if (widget == null) |
| + if (widget == null) { |
| + _didReachLastChild = true; |
| break; |
| + } |
| _Key widgetKey = new _Key.fromWidget(widget); |
| if (_offsets.last > startOffset) { |
| newChildren[widgetKey] = widget; |
| @@ -238,6 +253,7 @@ class BlockViewport extends RenderObjectWrapper { |
| } |
| } |
| assert(haveChildren != null); |
| + assert(!haveChildren ? _didReachLastChild : true); |
|
Hixie
2015/07/11 00:10:13
haveChildren || _didReachLastChild
hansmuller
2015/07/11 00:13:17
Done.
|
| assert(startIndex >= 0); |
| assert(startIndex < _offsets.length); |
| @@ -249,8 +265,10 @@ class BlockViewport extends RenderObjectWrapper { |
| while (_offsets[index] < endOffset) { |
| if (!builtChildren.containsKey(index)) { |
| Widget widget = _getWidget(index, innerConstraints); |
| - if (widget == null) |
| - break; // reached the end of the list |
| + if (widget == null) { |
| + _didReachLastChild = true; |
| + break; |
| + } |
| newChildren[new _Key.fromWidget(widget)] = widget; |
| builtChildren[index] = widget; |
| } |
| @@ -287,6 +305,15 @@ class BlockViewport extends RenderObjectWrapper { |
| _childrenByKey = newChildren; |
| _currentStartIndex = startIndex; |
| _currentChildCount = _childrenByKey.length; |
| + |
| + if (onLayoutChanged != null) { |
| + onLayoutChanged( |
| + _currentStartIndex, |
| + _currentChildCount, |
| + new UnmodifiableListView<double>(_offsets), |
| + _didReachLastChild |
| + ); |
| + } |
| } |
| } |