From 32784d35f9d75e0eb570d1ad157099afefcb6d08 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Tue, 31 Jan 2017 17:34:02 -0800 Subject: [PATCH] Revert "Add SliverGrid and ScrollGrid" (#7769) --- .../lib/demo/grid_list_demo.dart | 76 ++-- packages/flutter/lib/rendering.dart | 1 - .../flutter/lib/src/rendering/sliver.dart | 30 +- .../lib/src/rendering/sliver_app_bar.dart | 18 +- .../lib/src/rendering/sliver_block.dart | 13 +- .../lib/src/rendering/sliver_grid.dart | 426 ------------------ .../lib/src/rendering/sliver_list.dart | 11 +- .../rendering/sliver_multi_box_adaptor.dart | 29 +- .../lib/src/rendering/sliver_padding.dart | 11 +- .../flutter/lib/src/widgets/scroll_view.dart | 125 ++--- packages/flutter/lib/src/widgets/sliver.dart | 120 +---- .../test/rendering/slivers_block_test.dart | 2 +- packages/flutter/test/widgets/block_test.dart | 22 +- .../test/widgets/scroll_grid_test.dart | 306 ------------- .../test/widgets/scroll_view_test.dart | 57 ++- packages/flutter/test/widgets/states.dart | 56 --- 16 files changed, 186 insertions(+), 1117 deletions(-) delete mode 100644 packages/flutter/lib/src/rendering/sliver_grid.dart delete mode 100644 packages/flutter/test/widgets/scroll_grid_test.dart delete mode 100644 packages/flutter/test/widgets/states.dart diff --git a/examples/flutter_gallery/lib/demo/grid_list_demo.dart b/examples/flutter_gallery/lib/demo/grid_list_demo.dart index c85aaa19bb..fd8597bd75 100644 --- a/examples/flutter_gallery/lib/demo/grid_list_demo.dart +++ b/examples/flutter_gallery/lib/demo/grid_list_demo.dart @@ -131,9 +131,9 @@ class _GridPhotoViewerState extends State with SingleTickerProv ..translate(_offset.dx, _offset.dy) ..scale(_scale), child: new ClipRect( - child: new Image.asset(config.photo.assetName, fit: ImageFit.cover), - ), - ), + child: new Image.asset(config.photo.assetName, fit: ImageFit.cover) + ) + ) ); } ); @@ -200,11 +200,11 @@ class GridDemoPhotoItem extends StatelessWidget { backgroundColor: Colors.black45, leading: new Icon( icon, - color: Colors.white, - ), - ), + color: Colors.white + ) + ) ), - child: image, + child: image ); case GridDemoTileStyle.twoLine: @@ -217,11 +217,11 @@ class GridDemoPhotoItem extends StatelessWidget { subtitle: new _GridTitleText(photo.caption), trailing: new Icon( icon, - color: Colors.white, - ), - ), + color: Colors.white + ) + ) ), - child: image, + child: image ); } assert(tileStyle != null); @@ -245,62 +245,62 @@ class GridListDemoState extends State { new Photo( assetName: 'packages/flutter_gallery_assets/landscape_0.jpg', title: 'Philippines', - caption: 'Batad rice terraces', + caption: 'Batad rice terraces' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_1.jpg', title: 'Italy', - caption: 'Ceresole Reale', + caption: 'Ceresole Reale' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_2.jpg', title: 'Somewhere', - caption: 'Beautiful mountains', + caption: 'Beautiful mountains' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_3.jpg', title: 'A place', - caption: 'Beautiful hills', + caption: 'Beautiful hills' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_4.jpg', title: 'New Zealand', - caption: 'View from the van', + caption: 'View from the van' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_5.jpg', title: 'Autumn', - caption: 'The golden season', + caption: 'The golden season' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_6.jpg', title: 'Germany', - caption: 'Englischer Garten', + caption: 'Englischer Garten' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_7.jpg', title: 'A country', - caption: 'Grass fields', + caption: 'Grass fields' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_8.jpg', title: 'Mountain country', - caption: 'River forest', + caption: 'River forest' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_9.jpg', title: 'Alpine place', - caption: 'Green hills', + caption: 'Green hills' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_10.jpg', title: 'Desert land', - caption: 'Blue skies', + caption: 'Blue skies' ), new Photo( assetName: 'packages/flutter_gallery_assets/landscape_11.jpg', title: 'Narnia', - caption: 'Rocks and rivers', + caption: 'Rocks and rivers' ), ]; @@ -325,29 +325,31 @@ class GridListDemoState extends State { itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: GridDemoTileStyle.imageOnly, - child: new Text('Image only'), + child: new Text('Image only') ), new PopupMenuItem( value: GridDemoTileStyle.oneLine, - child: new Text('One line'), + child: new Text('One line') ), new PopupMenuItem( value: GridDemoTileStyle.twoLine, - child: new Text('Two line'), - ), - ], - ), - ], + child: new Text('Two line') + ) + ] + ) + ] ), body: new Column( children: [ new Expanded( - child: new ScrollGrid.count( - crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3, - mainAxisSpacing: 4.0, - crossAxisSpacing: 4.0, - padding: const EdgeInsets.all(4.0), - childAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3, + child: new ScrollableGrid( + delegate: new FixedColumnCountGridDelegate( + columnCount: (orientation == Orientation.portrait) ? 2 : 3, + rowSpacing: 4.0, + columnSpacing: 4.0, + padding: const EdgeInsets.all(4.0), + tileAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3 + ), children: photos.map((Photo photo) { return new GridDemoPhotoItem( photo: photo, @@ -358,7 +360,7 @@ class GridListDemoState extends State { }); } ); - }).toList(), + }) ) ) ] diff --git a/packages/flutter/lib/rendering.dart b/packages/flutter/lib/rendering.dart index 9a4f529790..7ad8fb7a70 100644 --- a/packages/flutter/lib/rendering.dart +++ b/packages/flutter/lib/rendering.dart @@ -47,7 +47,6 @@ export 'src/rendering/shifted_box.dart'; export 'src/rendering/sliver.dart'; export 'src/rendering/sliver_app_bar.dart'; export 'src/rendering/sliver_block.dart'; -export 'src/rendering/sliver_grid.dart'; export 'src/rendering/sliver_list.dart'; export 'src/rendering/sliver_multi_box_adaptor.dart'; export 'src/rendering/sliver_padding.dart'; diff --git a/packages/flutter/lib/src/rendering/sliver.dart b/packages/flutter/lib/src/rendering/sliver.dart index a108fe348f..7827a61a8e 100644 --- a/packages/flutter/lib/src/rendering/sliver.dart +++ b/packages/flutter/lib/src/rendering/sliver.dart @@ -282,9 +282,7 @@ class SliverConstraints extends Constraints { BoxConstraints asBoxConstraints({ double minExtent: 0.0, double maxExtent: double.INFINITY, - double crossAxisExtent, }) { - crossAxisExtent ??= this.crossAxisExtent; switch (axis) { case Axis.horizontal: return new BoxConstraints( @@ -817,16 +815,13 @@ abstract class RenderSliver extends RenderObject { /// the [RenderSliverHelpers] mixin and do not call this method yourself, you /// do not need to implement this method. @protected - double childMainAxisPosition(@checked RenderObject child) { + double childPosition(@checked RenderObject child) { assert(() { throw new FlutterError('$runtimeType does not implement childPosition.'); }); return 0.0; } - @protected - double childCrossAxisPosition(@checked RenderObject child) => 0.0; - @override void applyPaintTransform(RenderObject child, Matrix4 transform) { assert(() { @@ -1003,25 +998,24 @@ abstract class RenderSliverHelpers implements RenderSliver { /// This function takes care of converting the position from the sliver /// coordinate system to the cartesian coordinate system used by [RenderBox]. /// - /// This function relies on [childMainAxisPosition] to determine the position of + /// This function relies on [childPosition] to determine the position of /// child in question. /// /// Calling this for a child that is not visible is not valid. @protected bool hitTestBoxChild(HitTestResult result, RenderBox child, { @required double mainAxisPosition, @required double crossAxisPosition }) { final bool rightWayUp = _getRightWayUp(constraints); - double absolutePosition = mainAxisPosition - childMainAxisPosition(child); - final double absoluteCrossAxisPosition = crossAxisPosition - childCrossAxisPosition(child); + double absolutePosition = mainAxisPosition - childPosition(child); assert(constraints.axis != null); switch (constraints.axis) { case Axis.horizontal: if (!rightWayUp) absolutePosition = child.size.width - absolutePosition; - return child.hitTest(result, position: new Point(absolutePosition, absoluteCrossAxisPosition)); + return child.hitTest(result, position: new Point(absolutePosition, crossAxisPosition)); case Axis.vertical: if (!rightWayUp) absolutePosition = child.size.height - absolutePosition; - return child.hitTest(result, position: new Point(absoluteCrossAxisPosition, absolutePosition)); + return child.hitTest(result, position: new Point(crossAxisPosition, absolutePosition)); } return false; } @@ -1029,27 +1023,25 @@ abstract class RenderSliverHelpers implements RenderSliver { /// Utility function for [applyPaintTransform] for use when the children are /// [RenderBox] widgets. /// - /// This function turns the value returned by [childMainAxisPosition] and - /// [childCrossAxisPosition]for the child in question into a translation that - /// it then applies to the given matrix. + /// This function turns the value returned by [childPosition] for the child in + /// question into a translation that it then applies to the given matrix. /// /// Calling this for a child that is not visible is not valid. @protected void applyPaintTransformForBoxChild(RenderBox child, Matrix4 transform) { final bool rightWayUp = _getRightWayUp(constraints); - double delta = childMainAxisPosition(child); - final double crossAxisDelta = childCrossAxisPosition(child); + double delta = childPosition(child); assert(constraints.axis != null); switch (constraints.axis) { case Axis.horizontal: if (!rightWayUp) delta = geometry.paintExtent - child.size.width - delta; - transform.translate(delta, crossAxisDelta); + transform.translate(delta, 0.0); break; case Axis.vertical: if (!rightWayUp) delta = geometry.paintExtent - child.size.height - delta; - transform.translate(crossAxisDelta, delta); + transform.translate(0.0, delta); break; } } @@ -1846,7 +1838,7 @@ class RenderSliverToBoxAdapter extends RenderSliver with RenderObjectWithChildMi } @override - double childMainAxisPosition(RenderBox child) { + double childPosition(RenderBox child) { return -constraints.scrollOffset; } diff --git a/packages/flutter/lib/src/rendering/sliver_app_bar.dart b/packages/flutter/lib/src/rendering/sliver_app_bar.dart index f3ce3221d8..b2230fe9e1 100644 --- a/packages/flutter/lib/src/rendering/sliver_app_bar.dart +++ b/packages/flutter/lib/src/rendering/sliver_app_bar.dart @@ -132,7 +132,7 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil /// /// If there is no child, this should return 0.0. @override - double childMainAxisPosition(@checked RenderObject child) => super.childMainAxisPosition(child); + double childPosition(@checked RenderObject child) => super.childPosition(child); @override bool hitTestChildren(HitTestResult result, { @required double mainAxisPosition, @required double crossAxisPosition }) { @@ -155,16 +155,16 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil assert(constraints.axisDirection != null); switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { case AxisDirection.up: - offset += new Offset(0.0, geometry.paintExtent - childMainAxisPosition(child) - childExtent); + offset += new Offset(0.0, geometry.paintExtent - childPosition(child) - childExtent); break; case AxisDirection.down: - offset += new Offset(0.0, childMainAxisPosition(child)); + offset += new Offset(0.0, childPosition(child)); break; case AxisDirection.left: - offset += new Offset(geometry.paintExtent - childMainAxisPosition(child) - childExtent, 0.0); + offset += new Offset(geometry.paintExtent - childPosition(child) - childExtent, 0.0); break; case AxisDirection.right: - offset += new Offset(childMainAxisPosition(child), 0.0); + offset += new Offset(childPosition(child), 0.0); break; } context.paintChild(child, offset); @@ -180,7 +180,7 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil description.add('maxExtent: EXCEPTION (${e.runtimeType}) WHILE COMPUTING MAX EXTENT'); } try { - description.add('child position: ${childMainAxisPosition(child).toStringAsFixed(1)}'); + description.add('child position: ${childPosition(child).toStringAsFixed(1)}'); } catch (e) { description.add('child position: EXCEPTION (${e.runtimeType}) WHILE COMPUTING CHILD POSITION'); } @@ -216,7 +216,7 @@ abstract class RenderSliverScrollingAppBar extends RenderSliverAppBar { } @override - double childMainAxisPosition(RenderBox child) { + double childPosition(RenderBox child) { assert(child == this.child); return _childPosition; } @@ -246,7 +246,7 @@ abstract class RenderSliverPinnedAppBar extends RenderSliverAppBar { } @override - double childMainAxisPosition(RenderBox child) { + double childPosition(RenderBox child) { assert(child == this.child); return constraints?.overlap; } @@ -298,7 +298,7 @@ abstract class RenderSliverFloatingAppBar extends RenderSliverAppBar { } @override - double childMainAxisPosition(RenderBox child) { + double childPosition(RenderBox child) { assert(child == this.child); return _childPosition; } diff --git a/packages/flutter/lib/src/rendering/sliver_block.dart b/packages/flutter/lib/src/rendering/sliver_block.dart index 991240ff95..9fbaa0509e 100644 --- a/packages/flutter/lib/src/rendering/sliver_block.dart +++ b/packages/flutter/lib/src/rendering/sliver_block.dart @@ -184,18 +184,17 @@ class RenderSliverBlock extends RenderSliverMultiBoxAdaptor { collectGarbage(leadingGarbage, trailingGarbage); assert(debugAssertChildListIsNonEmptyAndContiguous()); - double estimatedMaxScrollOffset; + double estimatedTotalExtent; if (reachedEnd) { - estimatedMaxScrollOffset = endScrollOffset; + estimatedTotalExtent = endScrollOffset; } else { - estimatedMaxScrollOffset = childManager.estimateMaxScrollOffset( - constraints, + estimatedTotalExtent = childManager.estimateScrollOffsetExtent( firstIndex: indexOf(firstChild), lastIndex: indexOf(lastChild), leadingScrollOffset: offsetOf(firstChild), trailingScrollOffset: endScrollOffset, ); - assert(estimatedMaxScrollOffset >= endScrollOffset - offsetOf(firstChild)); + assert(estimatedTotalExtent >= endScrollOffset - offsetOf(firstChild)); } final double paintedExtent = calculatePaintOffset( constraints, @@ -203,9 +202,9 @@ class RenderSliverBlock extends RenderSliverMultiBoxAdaptor { to: endScrollOffset, ); geometry = new SliverGeometry( - scrollExtent: estimatedMaxScrollOffset, + scrollExtent: estimatedTotalExtent, paintExtent: paintedExtent, - maxPaintExtent: estimatedMaxScrollOffset, + maxPaintExtent: estimatedTotalExtent, // Conservative to avoid flickering away the clip during scroll. hasVisualOverflow: endScrollOffset > targetEndScrollOffset || constraints.scrollOffset > 0.0, ); diff --git a/packages/flutter/lib/src/rendering/sliver_grid.dart b/packages/flutter/lib/src/rendering/sliver_grid.dart deleted file mode 100644 index d216fffbde..0000000000 --- a/packages/flutter/lib/src/rendering/sliver_grid.dart +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:math' as math; - -import 'package:meta/meta.dart'; - -import 'box.dart'; -import 'object.dart'; -import 'sliver.dart'; -import 'sliver_multi_box_adaptor.dart'; - -/// Describes the placement of a child in a [RenderSliverGrid]. -/// -/// See also: -/// -/// * [SliverGridDelegate.getGeometryForChildIndex], which returns this object -/// to describe the child's placement. -/// * [RenderSliverGrid], which uses this class during its -/// [RenderSliverGrid.performLayout] method. -class SliverGridGeometry { - /// Creates an object that describes the placement of a child in a [RenderSliverGrid]. - const SliverGridGeometry({ - this.scrollOffset, - this.crossAxisOffset, - this.mainAxisExtent, - this.crossAxisExtent, - }); - - /// The scroll offset of the leading edge of the child relative to the leading - /// edge of the parent. - final double scrollOffset; - - /// The offset of the child in the non-scrolling axis. - /// - /// If the scroll axis is vertical, this offset is from the left-most edge of - /// the parent to the left-most edge of the child. If the scroll axis is - /// horizontal, this offset is from the top-most edge of the parent to the - /// top-most edge of the child. - final double crossAxisOffset; - - /// The extent of the child in the scrolling axis. - /// - /// If the scroll axis is vertical, this extent is the child's height. If the - /// scroll axis is horizontal, this extent is the child's width. - final double mainAxisExtent; - - /// The extent of the child in the non-scrolling axis. - /// - /// If the scroll axis is vertical, this extent is the child's width. If the - /// scroll axis is horizontal, this extent is the child's height. - final double crossAxisExtent; - - /// Returns a tight [BoxConstraints] that forces the child to have the - /// required size. - BoxConstraints getBoxConstraints(SliverConstraints constraints) { - return constraints.asBoxConstraints( - minExtent: mainAxisExtent, - maxExtent: mainAxisExtent, - crossAxisExtent: crossAxisExtent, - ); - } -} - -class SliverGridParentData extends SliverMultiBoxAdaptorParentData { - double crossAxisOffset; - - @override - String toString() => 'crossAxisOffset=$crossAxisOffset; ${super.toString()}'; -} - -abstract class SliverGridDelegate { - /// Abstract const constructor. This constructor enables subclasses to provide - /// const constructors so that they can be used in const expressions. - const SliverGridDelegate(); - - int getMinChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset); - - int getMaxChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset); - - SliverGridGeometry getGeometryForChildIndex(SliverConstraints constraints, int index); - - double estimateMaxScrollOffset(SliverConstraints constraints, int childCount); - - bool shouldRelayout(@checked SliverGridDelegate oldDelegate); -} - -class SliverGridDelegateWithFixedCrossAxisCount extends SliverGridDelegate { - const SliverGridDelegateWithFixedCrossAxisCount({ - @required this.crossAxisCount, - this.mainAxisSpacing: 0.0, - this.crossAxisSpacing: 0.0, - this.childAspectRatio: 1.0, - }); - - /// The number of children in the cross axis. - final int crossAxisCount; - - /// The number of logical pixels between each child along the main axis. - final double mainAxisSpacing; - - /// The number of logical pixels between each child along the cross axis. - final double crossAxisSpacing; - - /// The ratio of the cross-axis to the main-axis extent of each child. - final double childAspectRatio; - - bool _debugAssertIsValid() { - assert(crossAxisCount > 0); - assert(mainAxisSpacing >= 0.0); - assert(crossAxisSpacing >= 0.0); - assert(childAspectRatio > 0.0); - return true; - } - - double _getMainAxisStride(double crossAxisExtent) { - final double usableCrossAxisExtent = crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); - final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; - final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; - return childMainAxisExtent + mainAxisSpacing; - } - - @override - int getMinChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset) { - assert(_debugAssertIsValid()); - return crossAxisCount * (scrollOffset ~/ _getMainAxisStride(constraints.crossAxisExtent)); - } - - @override - int getMaxChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset) { - assert(_debugAssertIsValid()); - final int mainAxisCount = (scrollOffset / _getMainAxisStride(constraints.crossAxisExtent)).ceil(); - return math.max(0, crossAxisCount * mainAxisCount - 1); - } - - @override - SliverGridGeometry getGeometryForChildIndex(SliverConstraints constraints, int index) { - final double usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); - final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; - final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; - final double mainAxisStride = childMainAxisExtent + mainAxisSpacing; - final double crossAxisStrid = childCrossAxisExtent + crossAxisSpacing; - assert(mainAxisStride == _getMainAxisStride(constraints.crossAxisExtent)); - - return new SliverGridGeometry( - scrollOffset: (index ~/ crossAxisCount) * mainAxisStride, - crossAxisOffset: (index % crossAxisCount) * crossAxisStrid, - mainAxisExtent: childMainAxisExtent, - crossAxisExtent: childCrossAxisExtent, - ); - } - - @override - double estimateMaxScrollOffset(SliverConstraints constraints, int childCount) { - if (childCount == null) - return null; - final int mainAxisCount = ((childCount - 1) / crossAxisCount).floor() + 1; - return _getMainAxisStride(constraints.crossAxisExtent) * mainAxisCount - mainAxisSpacing; - } - - @override - bool shouldRelayout(SliverGridDelegateWithFixedCrossAxisCount oldDelegate) { - return oldDelegate.crossAxisCount != crossAxisCount - || oldDelegate.mainAxisSpacing != mainAxisSpacing - || oldDelegate.crossAxisSpacing != crossAxisSpacing - || oldDelegate.childAspectRatio != childAspectRatio; - } -} - -/// A [GridDelegate] that fills the width with a variable number of tiles. -/// -/// This delegate will select a tile width that is as large as possible subject -/// to the following conditions: -/// -/// - The tile width evenly divides the width of the grid. -/// - The tile width is at most [maxTileWidth]. -class SliverGridDelegateWithMaxCrossAxisExtent extends SliverGridDelegate { - /// Creates a grid delegate that uses a max tile width. - /// - /// The [maxTileWidth] argument must not be null. - const SliverGridDelegateWithMaxCrossAxisExtent({ - @required this.maxCrossAxisExtent, - this.mainAxisSpacing: 0.0, - this.crossAxisSpacing: 0.0, - this.childAspectRatio: 1.0, - }); - - /// The number of children in the cross axis. - final double maxCrossAxisExtent; - - /// The number of logical pixels between each child along the main axis. - final double mainAxisSpacing; - - /// The number of logical pixels between each child along the cross axis. - final double crossAxisSpacing; - - /// The ratio of the cross-axis to the main-axis extent of each child. - final double childAspectRatio; - - bool _debugAssertIsValid() { - assert(maxCrossAxisExtent > 0.0); - assert(mainAxisSpacing >= 0.0); - assert(crossAxisSpacing >= 0.0); - assert(childAspectRatio > 0.0); - return true; - } - - int _getCrossAxisCount(double crossAxisExtent) { - return (crossAxisExtent / (maxCrossAxisExtent + crossAxisSpacing)).ceil(); - } - - double _getMainAxisStride(double crossAxisExtent, int crossAxisCount) { - final double usableCrossAxisExtent = crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); - final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; - final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; - return childMainAxisExtent + mainAxisSpacing; - } - - @override - int getMinChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset) { - assert(_debugAssertIsValid()); - final double crossAxisExtent = constraints.crossAxisExtent; - final int crossAxisCount = _getCrossAxisCount(crossAxisExtent); - return crossAxisCount * (scrollOffset ~/ _getMainAxisStride(crossAxisExtent, crossAxisCount)); - } - - @override - int getMaxChildIndexForScrollOffset(SliverConstraints constraints, double scrollOffset) { - assert(_debugAssertIsValid()); - final double crossAxisExtent = constraints.crossAxisExtent; - final int crossAxisCount = _getCrossAxisCount(crossAxisExtent); - final int mainAxisCount = (scrollOffset / _getMainAxisStride(crossAxisExtent, crossAxisCount)).ceil(); - return math.max(0, crossAxisCount * mainAxisCount - 1); - } - - @override - SliverGridGeometry getGeometryForChildIndex(SliverConstraints constraints, int index) { - final int crossAxisCount = _getCrossAxisCount(constraints.crossAxisExtent); - final double usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); - final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; - final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; - final double mainAxisStride = childMainAxisExtent + mainAxisSpacing; - final double crossAxisStrid = childCrossAxisExtent + crossAxisSpacing; - assert(mainAxisStride == _getMainAxisStride(constraints.crossAxisExtent, crossAxisCount)); - - return new SliverGridGeometry( - scrollOffset: (index ~/ crossAxisCount) * mainAxisStride, - crossAxisOffset: (index % crossAxisCount) * crossAxisStrid, - mainAxisExtent: childMainAxisExtent, - crossAxisExtent: childCrossAxisExtent, - ); - } - - @override - double estimateMaxScrollOffset(SliverConstraints constraints, int childCount) { - if (childCount == null) - return null; - final double crossAxisExtent = constraints.crossAxisExtent; - final int crossAxisCount = _getCrossAxisCount(crossAxisExtent); - final int mainAxisCount = ((childCount - 1) / crossAxisCount).floor() + 1; - return _getMainAxisStride(crossAxisExtent, crossAxisCount) * mainAxisCount - mainAxisSpacing; - } - - @override - bool shouldRelayout(SliverGridDelegateWithMaxCrossAxisExtent oldDelegate) { - return oldDelegate.maxCrossAxisExtent != maxCrossAxisExtent - || oldDelegate.mainAxisSpacing != mainAxisSpacing - || oldDelegate.crossAxisSpacing != crossAxisSpacing - || oldDelegate.childAspectRatio != childAspectRatio; - } -} - -class RenderSliverGrid extends RenderSliverMultiBoxAdaptor { - RenderSliverGrid({ - @required RenderSliverBoxChildManager childManager, - @required SliverGridDelegate gridDelegate, - }) : _gridDelegate = gridDelegate, - super(childManager: childManager) { - gridDelegate != null; - } - - @override - void setupParentData(RenderObject child) { - if (child.parentData is! SliverGridParentData) - child.parentData = new SliverGridParentData(); - } - - SliverGridDelegate get gridDelegate => _gridDelegate; - SliverGridDelegate _gridDelegate; - - set gridDelegate(SliverGridDelegate newDelegate) { - assert(newDelegate != null); - if (_gridDelegate == newDelegate) - return; - if (newDelegate.runtimeType != _gridDelegate.runtimeType || - newDelegate.shouldRelayout(_gridDelegate)) - markNeedsLayout(); - _gridDelegate = newDelegate; - } - - @override - double childCrossAxisPosition(RenderBox child) { - final SliverGridParentData childParentData = child.parentData; - return childParentData.crossAxisOffset; - } - - @override - void performLayout() { - assert(childManager.debugAssertChildListLocked()); - final double scrollOffset = constraints.scrollOffset; - assert(scrollOffset >= 0.0); - final double remainingPaintExtent = constraints.remainingPaintExtent; - assert(remainingPaintExtent >= 0.0); - final double targetEndScrollOffset = scrollOffset + remainingPaintExtent; - - final int firstIndex = _gridDelegate.getMinChildIndexForScrollOffset(constraints, scrollOffset); - final int targetLastIndex = _gridDelegate.getMaxChildIndexForScrollOffset(constraints, targetEndScrollOffset); - - if (firstChild != null) { - final int oldFirstIndex = indexOf(firstChild); - final int oldLastIndex = indexOf(lastChild); - final int leadingGarbage = (firstIndex - oldFirstIndex).clamp(0, childCount); - final int trailingGarbage = (oldLastIndex - targetLastIndex).clamp(0, childCount); - if (leadingGarbage + trailingGarbage > 0) - collectGarbage(leadingGarbage, trailingGarbage); - } - - final SliverGridGeometry firstChildGridGeometry = _gridDelegate - .getGeometryForChildIndex(constraints, firstIndex); - double leadingScrollOffset = firstChildGridGeometry.scrollOffset; - double trailingScrollOffset = firstChildGridGeometry.scrollOffset; - - if (firstChild == null) { - if (!addInitialChild(index: firstIndex, - scrollOffset: firstChildGridGeometry.scrollOffset)) { - // There are no children. - geometry = SliverGeometry.zero; - return; - } - } - - RenderBox trailingChildWithLayout; - - for (int index = indexOf(firstChild) - 1; index >= firstIndex; --index) { - final SliverGridGeometry gridGeometry = _gridDelegate - .getGeometryForChildIndex(constraints, index); - final RenderBox child = insertAndLayoutLeadingChild( - gridGeometry.getBoxConstraints(constraints)); - final SliverGridParentData childParentData = child.parentData; - childParentData.scrollOffset = gridGeometry.scrollOffset; - childParentData.crossAxisOffset = gridGeometry.crossAxisOffset; - assert(childParentData.index == index); - trailingChildWithLayout ??= child; - if (gridGeometry.scrollOffset > trailingScrollOffset) - trailingScrollOffset = gridGeometry.scrollOffset; - } - - assert(offsetOf(firstChild) <= scrollOffset); - - if (trailingChildWithLayout == null) { - firstChild.layout(firstChildGridGeometry.getBoxConstraints(constraints)); - final SliverGridParentData childParentData = firstChild.parentData; - childParentData.crossAxisOffset = firstChildGridGeometry.crossAxisOffset; - assert(childParentData.scrollOffset == - firstChildGridGeometry.scrollOffset); - trailingChildWithLayout = firstChild; - } - - for (int index = indexOf(trailingChildWithLayout) + 1; index <= - targetLastIndex; ++index) { - final SliverGridGeometry gridGeometry = _gridDelegate - .getGeometryForChildIndex(constraints, index); - final BoxConstraints childConstraints = gridGeometry.getBoxConstraints( - constraints); - RenderBox child = childAfter(trailingChildWithLayout); - if (child == null) { - child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout); - if (child == null) { - // We have run out of children. - break; - } - } else { - child.layout(childConstraints); - } - trailingChildWithLayout = child; - assert(child != null); - final SliverGridParentData childParentData = child.parentData; - childParentData.scrollOffset = gridGeometry.scrollOffset; - childParentData.crossAxisOffset = gridGeometry.crossAxisOffset; - assert(childParentData.index == index); - if (gridGeometry.scrollOffset > trailingScrollOffset) - trailingScrollOffset = gridGeometry.scrollOffset; - } - - final int lastIndex = indexOf(lastChild); - - assert(debugAssertChildListIsNonEmptyAndContiguous()); - assert(indexOf(firstChild) == firstIndex); - assert(lastIndex <= targetLastIndex); - - final double estimatedTotalExtent = childManager.estimateMaxScrollOffset( - constraints, - firstIndex: firstIndex, - lastIndex: lastIndex, - leadingScrollOffset: leadingScrollOffset, - trailingScrollOffset: trailingScrollOffset, - ); - - final double paintedExtent = calculatePaintOffset( - constraints, - from: leadingScrollOffset, - to: trailingScrollOffset, - ); - - geometry = new SliverGeometry( - scrollExtent: estimatedTotalExtent, - paintExtent: paintedExtent, - maxPaintExtent: estimatedTotalExtent, - // Conservative to avoid complexity. - hasVisualOverflow: true, - ); - - assert(childManager.debugAssertChildListLocked()); - } -} diff --git a/packages/flutter/lib/src/rendering/sliver_list.dart b/packages/flutter/lib/src/rendering/sliver_list.dart index 8c6ef3e39c..864679874e 100644 --- a/packages/flutter/lib/src/rendering/sliver_list.dart +++ b/packages/flutter/lib/src/rendering/sliver_list.dart @@ -14,9 +14,7 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor { RenderSliverList({ @required RenderSliverBoxChildManager childManager, double itemExtent, - }) : _itemExtent = itemExtent, super(childManager: childManager) { - assert(itemExtent != null); - } + }) : _itemExtent = itemExtent, super(childManager: childManager); /// The main-axis extent of each item in the list. double get itemExtent => _itemExtent; @@ -107,8 +105,7 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor { assert(indexOf(firstChild) == firstIndex); assert(lastIndex <= targetLastIndex); - final double estimatedMaxScrollOffset = childManager.estimateMaxScrollOffset( - constraints, + final double estimatedTotalExtent = childManager.estimateScrollOffsetExtent( firstIndex: firstIndex, lastIndex: lastIndex, leadingScrollOffset: leadingScrollOffset, @@ -122,9 +119,9 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor { ); geometry = new SliverGeometry( - scrollExtent: estimatedMaxScrollOffset, + scrollExtent: estimatedTotalExtent, paintExtent: paintedExtent, - maxPaintExtent: estimatedMaxScrollOffset, + maxPaintExtent: estimatedTotalExtent, // Conservative to avoid flickering away the clip during scroll. hasVisualOverflow: lastIndex >= targetLastIndex || constraints.scrollOffset > 0.0, ); diff --git a/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart b/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart index 84727880ec..45e12eccf5 100644 --- a/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart +++ b/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart @@ -61,7 +61,7 @@ abstract class RenderSliverBoxChildManager { /// Must return the total distance from the start of the child with the /// earliest possible index to the end of the child with the last possible /// index. - double estimateMaxScrollOffset(SliverConstraints constraints, { + double estimateScrollOffsetExtent({ int firstIndex, int lastIndex, double leadingScrollOffset, @@ -304,7 +304,7 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver } @override - double childMainAxisPosition(RenderBox child) { + double childPosition(RenderBox child) { return offsetOf(child) - constraints.scrollOffset; } @@ -319,46 +319,37 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver return; // offset is to the top-left corner, regardless of our axis direction. // originOffset gives us the delta from the real origin to the origin in the axis direction. - Offset mainAxisUnit, crossAxisUnit, originOffset; + Offset unitOffset, originOffset; bool addExtent; switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) { case AxisDirection.up: - mainAxisUnit = const Offset(0.0, -1.0); - crossAxisUnit = const Offset(1.0, 0.0); + unitOffset = const Offset(0.0, -1.0); originOffset = offset + new Offset(0.0, geometry.paintExtent); addExtent = true; break; case AxisDirection.right: - mainAxisUnit = const Offset(1.0, 0.0); - crossAxisUnit = const Offset(0.0, 1.0); + unitOffset = const Offset(1.0, 0.0); originOffset = offset; addExtent = false; break; case AxisDirection.down: - mainAxisUnit = const Offset(0.0, 1.0); - crossAxisUnit = const Offset(1.0, 0.0); + unitOffset = const Offset(0.0, 1.0); originOffset = offset; addExtent = false; break; case AxisDirection.left: - mainAxisUnit = const Offset(-1.0, 0.0); - crossAxisUnit = const Offset(0.0, 1.0); + unitOffset = const Offset(-1.0, 0.0); originOffset = offset + new Offset(geometry.paintExtent, 0.0); addExtent = true; break; } - assert(mainAxisUnit != null); + assert(unitOffset != null); assert(addExtent != null); RenderBox child = firstChild; while (child != null) { - final double mainAxisDelta = childMainAxisPosition(child); - final double crossAxisDelta = childCrossAxisPosition(child); - Offset childOffset = new Offset( - originOffset.dx + mainAxisUnit.dx * mainAxisDelta + crossAxisUnit.dx * crossAxisDelta, - originOffset.dy + mainAxisUnit.dy * mainAxisDelta + crossAxisUnit.dy * crossAxisDelta, - ); + Offset childOffset = originOffset + unitOffset * childPosition(child); if (addExtent) - childOffset += mainAxisUnit * paintExtentOf(child); + childOffset += unitOffset * paintExtentOf(child); context.paintChild(child, childOffset); child = childAfter(child); } diff --git a/packages/flutter/lib/src/rendering/sliver_padding.dart b/packages/flutter/lib/src/rendering/sliver_padding.dart index bb328c6521..6d3731a86e 100644 --- a/packages/flutter/lib/src/rendering/sliver_padding.dart +++ b/packages/flutter/lib/src/rendering/sliver_padding.dart @@ -262,24 +262,17 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin 0.0) - return child.hitTest(result, mainAxisPosition: mainAxisPosition - childMainAxisPosition(child), crossAxisPosition: crossAxisPosition - childCrossAxisPosition(child)); + return child.hitTest(result, mainAxisPosition: mainAxisPosition - childPosition(child), crossAxisPosition: crossAxisPosition - startPadding); return false; } @override - double childMainAxisPosition(RenderSliver child) { + double childPosition(RenderSliver child) { assert(child != null); assert(child == this.child); return calculatePaintOffset(constraints, from: 0.0, to: beforePadding); } - @override - double childCrossAxisPosition(RenderSliver child) { - assert(child != null); - assert(child == this.child); - return startPadding; - } - @override void applyPaintTransform(RenderObject child, Matrix4 transform) { assert(child != null); diff --git a/packages/flutter/lib/src/widgets/scroll_view.dart b/packages/flutter/lib/src/widgets/scroll_view.dart index 676b49259e..fe0ed6cbff 100644 --- a/packages/flutter/lib/src/widgets/scroll_view.dart +++ b/packages/flutter/lib/src/widgets/scroll_view.dart @@ -3,31 +3,21 @@ // found in the LICENSE file. import 'package:flutter/rendering.dart'; -import 'package:meta/meta.dart'; import 'framework.dart'; import 'basic.dart'; import 'scrollable.dart'; import 'sliver.dart'; -AxisDirection _getDirection(BuildContext context, Axis scrollDirection) { - // TODO(abarth): Consider reading direction. - switch (scrollDirection) { - case Axis.horizontal: - return AxisDirection.right; - case Axis.vertical: - return AxisDirection.down; - } - return null; -} - class ScrollView extends StatelessWidget { ScrollView({ Key key, this.padding, this.scrollDirection: Axis.vertical, + this.anchor: 0.0, this.initialScrollOffset: 0.0, this.itemExtent, + this.center, this.children, }) : super(key: key); @@ -35,109 +25,50 @@ class ScrollView extends StatelessWidget { final Axis scrollDirection; + final double anchor; + final double initialScrollOffset; final double itemExtent; + final Key center; + final List children; - Widget _buildChildLayout() { + AxisDirection _getDirection(BuildContext context) { + // TODO(abarth): Consider reading direction. + switch (scrollDirection) { + case Axis.horizontal: + return AxisDirection.right; + case Axis.vertical: + return AxisDirection.down; + } + return null; + } + + @override + Widget build(BuildContext context) { final SliverChildListDelegate delegate = new SliverChildListDelegate(children); - if (itemExtent != null) { - return new SliverList( + Widget sliver; + + if (itemExtent == null) { + sliver = new SliverBlock(delegate: delegate); + } else { + sliver = new SliverList( delegate: delegate, itemExtent: itemExtent, ); } - return new SliverBlock(delegate: delegate); - } - - @override - Widget build(BuildContext context) { - Widget sliver = _buildChildLayout(); - if (padding != null) sliver = new SliverPadding(padding: padding, child: sliver); return new ScrollableViewport2( - axisDirection: _getDirection(context, scrollDirection), - initialScrollOffset: initialScrollOffset, - slivers: [ sliver ], - ); - } -} - -class ScrollGrid extends StatelessWidget { - ScrollGrid({ - Key key, - this.padding, - this.scrollDirection: Axis.vertical, - this.initialScrollOffset: 0.0, - this.gridDelegate, - this.children, - }) : super(key: key); - - ScrollGrid.count({ - Key key, - this.padding, - this.scrollDirection: Axis.vertical, - this.initialScrollOffset: 0.0, - @required int crossAxisCount, - double mainAxisSpacing: 0.0, - double crossAxisSpacing: 0.0, - double childAspectRatio: 1.0, - this.children, - }) : gridDelegate = new SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: crossAxisCount, - mainAxisSpacing: mainAxisSpacing, - crossAxisSpacing: crossAxisSpacing, - childAspectRatio: childAspectRatio, - ), super(key: key); - - ScrollGrid.extent({ - Key key, - this.padding, - this.scrollDirection: Axis.vertical, - this.initialScrollOffset: 0.0, - @required double maxCrossAxisExtent, - double mainAxisSpacing: 0.0, - double crossAxisSpacing: 0.0, - double childAspectRatio: 1.0, - this.children, - }) : gridDelegate = new SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: maxCrossAxisExtent, - mainAxisSpacing: mainAxisSpacing, - crossAxisSpacing: crossAxisSpacing, - childAspectRatio: childAspectRatio, - ), super(key: key); - - final EdgeInsets padding; - - final Axis scrollDirection; - - final double initialScrollOffset; - - final SliverGridDelegate gridDelegate; - - final List children; - - @override - Widget build(BuildContext context) { - final SliverChildListDelegate delegate = new SliverChildListDelegate(children); - - Widget sliver = new SliverGrid( - delegate: delegate, - gridDelegate: gridDelegate, - ); - - if (padding != null) - sliver = new SliverPadding(padding: padding, child: sliver); - - return new ScrollableViewport2( - axisDirection: _getDirection(context, scrollDirection), + axisDirection: _getDirection(context), + anchor: anchor, initialScrollOffset: initialScrollOffset, + center: center, slivers: [ sliver ], ); } diff --git a/packages/flutter/lib/src/widgets/sliver.dart b/packages/flutter/lib/src/widgets/sliver.dart index b5c5a63949..9be30b99e5 100644 --- a/packages/flutter/lib/src/widgets/sliver.dart +++ b/packages/flutter/lib/src/widgets/sliver.dart @@ -10,11 +10,6 @@ import 'package:flutter/rendering.dart'; import 'framework.dart'; import 'basic.dart'; -export 'package:flutter/rendering.dart' show - SliverGridDelegate, - SliverGridDelegateWithFixedCrossAxisCount, - SliverGridDelegateWithMaxCrossAxisExtent; - abstract class SliverChildDelegate { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. @@ -22,23 +17,24 @@ abstract class SliverChildDelegate { Widget build(BuildContext context, int index); - /// Returns an estimate of the number of children this delegate will build. - /// - /// Used to estimate the maximum scroll offset if [estimateMaxScrollOffset] - /// returns null. - /// - /// Return null if there are an unbounded number of children or if it would - /// be too difficult to estimate the number of children. - int get estimatedChildCount => null; + bool shouldRebuild(@checked SliverChildDelegate oldDelegate); - double estimateMaxScrollOffset( + int get childCount; + + double estimateScrollOffsetExtent( int firstIndex, int lastIndex, double leadingScrollOffset, double trailingScrollOffset, - ) => null; - - bool shouldRebuild(@checked SliverChildDelegate oldDelegate); + ) { + final int childCount = this.childCount; + if (lastIndex == childCount - 1) + return trailingScrollOffset; + final int reifiedCount = lastIndex - firstIndex + 1; + final double averageExtent = (trailingScrollOffset - leadingScrollOffset) / reifiedCount; + final int remainingCount = childCount - lastIndex - 1; + return trailingScrollOffset + averageExtent * remainingCount; + } } // /// @@ -68,13 +64,13 @@ class SliverChildListDelegate extends SliverChildDelegate { return children[index]; } - @override - int get estimatedChildCount => children.length; - @override bool shouldRebuild(@checked SliverChildListDelegate oldDelegate) { return children != oldDelegate.children; } + + @override + int get childCount => children.length; } abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { @@ -93,22 +89,6 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { @override RenderSliverMultiBoxAdaptor createRenderObject(BuildContext context); - double estimateMaxScrollOffset( - SliverConstraints constraints, - int firstIndex, - int lastIndex, - double leadingScrollOffset, - double trailingScrollOffset, - ) { - assert(lastIndex >= firstIndex); - return delegate.estimateMaxScrollOffset( - firstIndex, - lastIndex, - leadingScrollOffset, - trailingScrollOffset, - ); - } - @override void debugFillDescription(List description) { super.debugFillDescription(description); @@ -150,44 +130,6 @@ class SliverList extends SliverMultiBoxAdaptorWidget { } } -class SliverGrid extends SliverMultiBoxAdaptorWidget { - SliverGrid({ - Key key, - @required SliverChildDelegate delegate, - @required this.gridDelegate, - }) : super(key: key, delegate: delegate); - - final SliverGridDelegate gridDelegate; - - @override - RenderSliverGrid createRenderObject(BuildContext context) { - final SliverMultiBoxAdaptorElement element = context; - return new RenderSliverGrid(childManager: element, gridDelegate: gridDelegate); - } - - @override - void updateRenderObject(BuildContext context, RenderSliverGrid renderObject) { - renderObject.gridDelegate = gridDelegate; - } - - @override - double estimateMaxScrollOffset( - SliverConstraints constraints, - int firstIndex, - int lastIndex, - double leadingScrollOffset, - double trailingScrollOffset, - ) { - return super.estimateMaxScrollOffset( - constraints, - firstIndex, - lastIndex, - leadingScrollOffset, - trailingScrollOffset, - ) ?? gridDelegate.estimateMaxScrollOffset(constraints, delegate.estimatedChildCount); - } -} - class SliverMultiBoxAdaptorElement extends RenderObjectElement implements RenderSliverBoxChildManager { SliverMultiBoxAdaptorElement(SliverMultiBoxAdaptorWidget widget) : super(widget); @@ -299,41 +241,19 @@ class SliverMultiBoxAdaptorElement extends RenderObjectElement implements Render }); } - double _extrapolateMaxScrollOffset( - int firstIndex, - int lastIndex, - double leadingScrollOffset, - double trailingScrollOffset, - ) { - final int childCount = widget.delegate.estimatedChildCount; - if (childCount == null) - return double.INFINITY; - if (lastIndex == childCount - 1) - return trailingScrollOffset; - final int reifiedCount = lastIndex - firstIndex + 1; - final double averageExtent = (trailingScrollOffset - leadingScrollOffset) / reifiedCount; - final int remainingCount = childCount - lastIndex - 1; - return trailingScrollOffset + averageExtent * remainingCount; - } - @override - double estimateMaxScrollOffset(SliverConstraints constraints, { + double estimateScrollOffsetExtent({ int firstIndex, int lastIndex, double leadingScrollOffset, double trailingScrollOffset, }) { - return widget.estimateMaxScrollOffset( - constraints, + assert(lastIndex >= firstIndex); + return widget.delegate.estimateScrollOffsetExtent( firstIndex, lastIndex, leadingScrollOffset, - trailingScrollOffset, - ) ?? _extrapolateMaxScrollOffset( - firstIndex, - lastIndex, - leadingScrollOffset, - trailingScrollOffset, + trailingScrollOffset ); } diff --git a/packages/flutter/test/rendering/slivers_block_test.dart b/packages/flutter/test/rendering/slivers_block_test.dart index af8448430d..ae7cc5a03c 100644 --- a/packages/flutter/test/rendering/slivers_block_test.dart +++ b/packages/flutter/test/rendering/slivers_block_test.dart @@ -43,7 +43,7 @@ class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager { } @override - double estimateMaxScrollOffset(SliverConstraints constraints, { + double estimateScrollOffsetExtent({ int firstIndex, int lastIndex, double leadingScrollOffset, diff --git a/packages/flutter/test/widgets/block_test.dart b/packages/flutter/test/widgets/block_test.dart index debb7a4547..df40d3b6fe 100644 --- a/packages/flutter/test/widgets/block_test.dart +++ b/packages/flutter/test/widgets/block_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; final Key blockKey = new Key('test'); @@ -121,7 +120,7 @@ void main() { expect(key.currentState.scrollOffset, 0.0); }); - testWidgets('SliverBlockChildListDelegate.estimateMaxScrollOffset hits end', (WidgetTester tester) async { + testWidgets('SliverBlockChildListDelegate.estimateScrollOffsetExtent hits end', (WidgetTester tester) async { SliverChildListDelegate delegate = new SliverChildListDelegate([ new Container(), new Container(), @@ -130,23 +129,6 @@ void main() { new Container(), ]); - await tester.pumpWidget(new ScrollableViewport2( - slivers: [ - new SliverBlock( - delegate: delegate, - ), - ], - )); - - final SliverMultiBoxAdaptorElement element = tester.element(find.byType(SliverBlock)); - - final double maxScrollOffset = element.estimateMaxScrollOffset( - null, - firstIndex: 3, - lastIndex: 4, - leadingScrollOffset: 25.0, - trailingScrollOffset: 26.0 - ); - expect(maxScrollOffset, equals(26.0)); + expect(delegate.estimateScrollOffsetExtent(3, 4, 25.0, 26.0), equals(26.0)); }); } diff --git a/packages/flutter/test/widgets/scroll_grid_test.dart b/packages/flutter/test/widgets/scroll_grid_test.dart deleted file mode 100644 index 17c5344628..0000000000 --- a/packages/flutter/test/widgets/scroll_grid_test.dart +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter/widgets.dart'; - -import 'states.dart'; - -void main() { - testWidgets('Empty ScrollGrid', (WidgetTester tester) async { - await tester.pumpWidget(new ScrollGrid.count( - crossAxisCount: 4, - children: const [], - )); - }); - - testWidgets('ScrollGrid.count control test', (WidgetTester tester) async { - List log = []; - - await tester.pumpWidget(new ScrollGrid.count( - crossAxisCount: 4, - children: kStates.map((String state) { - return new GestureDetector( - onTap: () { - log.add(state); - }, - child: new Container( - decoration: const BoxDecoration( - backgroundColor: const Color(0xFF0000FF), - ), - child: new Text(state), - ), - ); - }).toList(), - )); - - expect(tester.getSize(find.text('Arkansas')), equals(const Size(200.0, 200.0))); - - for (int i = 0; i < 8; ++i) { - await tester.tap(find.text(kStates[i])); - expect(log, equals([kStates[i]])); - log.clear(); - } - - expect(find.text(kStates[12]), findsNothing); - expect(find.text('Nevada'), findsNothing); - - await tester.scroll(find.text('Arkansas'), const Offset(0.0, -200.0)); - await tester.pump(); - - for (int i = 0; i < 4; ++i) - expect(find.text(kStates[i]), findsNothing); - - for (int i = 4; i < 12; ++i) { - await tester.tap(find.text(kStates[i])); - expect(log, equals([kStates[i]])); - log.clear(); - } - - await tester.scroll(find.text('Delaware'), const Offset(0.0, -4000.0)); - await tester.pump(); - - expect(find.text('Alabama'), findsNothing); - expect(find.text('Pennsylvania'), findsNothing); - - expect(tester.getCenter(find.text('Tennessee')), - equals(const Point(300.0, 100.0))); - - await tester.tap(find.text('Tennessee')); - expect(log, equals(['Tennessee'])); - log.clear(); - - await tester.scroll(find.text('Tennessee'), const Offset(0.0, 200.0)); - await tester.pump(); - - await tester.tap(find.text('Tennessee')); - expect(log, equals(['Tennessee'])); - log.clear(); - - await tester.tap(find.text('Pennsylvania')); - expect(log, equals(['Pennsylvania'])); - log.clear(); - }); - - testWidgets('ScrollGrid.extent control test', (WidgetTester tester) async { - List log = []; - - await tester.pumpWidget(new ScrollGrid.extent( - maxCrossAxisExtent: 200.0, - children: kStates.map((String state) { - return new GestureDetector( - onTap: () { - log.add(state); - }, - child: new Container( - decoration: const BoxDecoration( - backgroundColor: const Color(0xFF0000FF), - ), - child: new Text(state), - ), - ); - }).toList(), - )); - - expect(tester.getSize(find.text('Arkansas')), equals(const Size(200.0, 200.0))); - - for (int i = 0; i < 8; ++i) { - await tester.tap(find.text(kStates[i])); - expect(log, equals([kStates[i]])); - log.clear(); - } - - expect(find.text('Nevada'), findsNothing); - - await tester.scroll(find.text('Arkansas'), const Offset(0.0, -4000.0)); - await tester.pump(); - - expect(find.text('Alabama'), findsNothing); - - expect(tester.getCenter(find.text('Tennessee')), - equals(const Point(300.0, 100.0))); - - await tester.tap(find.text('Tennessee')); - expect(log, equals(['Tennessee'])); - log.clear(); - }); - - testWidgets('ScrollGrid large scroll jump', (WidgetTester tester) async { - List log = []; - - await tester.pumpWidget( - new ScrollGrid.extent( - scrollDirection: Axis.horizontal, - maxCrossAxisExtent: 200.0, - childAspectRatio: 0.75, - children: new List.generate(80, (int i) { - return new Builder( - builder: (BuildContext context) { - log.add(i); - return new Container( - child: new Text('$i'), - ); - } - ); - }), - ), - ); - - expect(tester.getSize(find.text('4')), equals(const Size(200.0 / 0.75, 200.0))); - - expect(log, equals([ - 0, 1, 2, // col 0 - 3, 4, 5, // col 1 - 6, 7, 8, // col 2 - ])); - log.clear(); - - - Scrollable2State state = tester.state(find.byType(Scrollable2)); - AbsoluteScrollPosition position = state.position; - position.jumpTo(3025.0); - - expect(log, isEmpty); - await tester.pump(); - - expect(log, equals([ - 33, 34, 35, // col 11 - 36, 37, 38, // col 12 - 39, 40, 41, // col 13 - 42, 43, 44, // col 14 - ])); - log.clear(); - - position.jumpTo(975.0); - - expect(log, isEmpty); - await tester.pump(); - - expect(log, equals([ - 9, 10, 11, // col 3 - 12, 13, 14, // col 4 - 15, 16, 17, // col 5 - 18, 19, 20, // col 6 - ])); - log.clear(); - }); - - testWidgets('ScrollGrid - change crossAxisCount', (WidgetTester tester) async { - List log = []; - - await tester.pumpWidget( - new ScrollGrid( - gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - ), - children: new List.generate(40, (int i) { - return new Builder( - builder: (BuildContext context) { - log.add(i); - return new Container( - child: new Text('$i'), - ); - } - ); - }), - ), - ); - - expect(tester.getSize(find.text('4')), equals(const Size(200.0, 200.0))); - - expect(log, equals([ - 0, 1, 2, 3, // row 0 - 4, 5, 6, 7, // row 1 - 8, 9, 10, 11, // row 2 - ])); - log.clear(); - - await tester.pumpWidget( - new ScrollGrid( - gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - ), - children: new List.generate(40, (int i) { - return new Builder( - builder: (BuildContext context) { - log.add(i); - return new Container( - child: new Text('$i'), - ); - } - ); - }), - ), - ); - - expect(log, equals([ - 0, 1, 2, 3, // row 0 - 4, 5, 6, 7, // row 1 - 8, 9, 10, 11, // row 2 - ])); - log.clear(); - - expect(tester.getSize(find.text('3')), equals(const Size(400.0, 400.0))); - expect(find.text('4'), findsNothing); - }); - - testWidgets('ScrollGrid - change maxChildCrossAxisExtent', (WidgetTester tester) async { - List log = []; - - await tester.pumpWidget( - new ScrollGrid( - gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 200.0, - ), - children: new List.generate(40, (int i) { - return new Builder( - builder: (BuildContext context) { - log.add(i); - return new Container( - child: new Text('$i'), - ); - } - ); - }), - ), - ); - - expect(tester.getSize(find.text('4')), equals(const Size(200.0, 200.0))); - - expect(log, equals([ - 0, 1, 2, 3, // row 0 - 4, 5, 6, 7, // row 1 - 8, 9, 10, 11, // row 2 - ])); - log.clear(); - - await tester.pumpWidget( - new ScrollGrid( - gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 400.0, - ), - children: new List.generate(40, (int i) { - return new Builder( - builder: (BuildContext context) { - log.add(i); - return new Container( - child: new Text('$i'), - ); - } - ); - }), - ), - ); - - expect(log, equals([ - 0, 1, 2, 3, // row 0 - 4, 5, 6, 7, // row 1 - 8, 9, 10, 11, // row 2 - ])); - log.clear(); - - expect(tester.getSize(find.text('3')), equals(const Size(400.0, 400.0))); - expect(find.text('4'), findsNothing); - }); -} diff --git a/packages/flutter/test/widgets/scroll_view_test.dart b/packages/flutter/test/widgets/scroll_view_test.dart index 93d896a85e..c6c420987a 100644 --- a/packages/flutter/test/widgets/scroll_view_test.dart +++ b/packages/flutter/test/widgets/scroll_view_test.dart @@ -5,14 +5,65 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'states.dart'; +const List _kStates = const [ + 'Alabama', + 'Alaska', + 'Arizona', + 'Arkansas', + 'California', + 'Colorado', + 'Connecticut', + 'Delaware', + 'Florida', + 'Georgia', + 'Hawaii', + 'Idaho', + 'Illinois', + 'Indiana', + 'Iowa', + 'Kansas', + 'Kentucky', + 'Louisiana', + 'Maine', + 'Maryland', + 'Massachusetts', + 'Michigan', + 'Minnesota', + 'Mississippi', + 'Missouri', + 'Montana', + 'Nebraska', + 'Nevada', + 'New Hampshire', + 'New Jersey', + 'New Mexico', + 'New York', + 'North Carolina', + 'North Dakota', + 'Ohio', + 'Oklahoma', + 'Oregon', + 'Pennsylvania', + 'Rhode Island', + 'South Carolina', + 'South Dakota', + 'Tennessee', + 'Texas', + 'Utah', + 'Vermont', + 'Virginia', + 'Washington', + 'West Virginia', + 'Wisconsin', + 'Wyoming', +]; void main() { testWidgets('ScrollView control test', (WidgetTester tester) async { List log = []; await tester.pumpWidget(new ScrollView( - children: kStates.map((String state) { + children: _kStates.map((String state) { return new GestureDetector( onTap: () { log.add(state); @@ -48,7 +99,7 @@ void main() { testWidgets('ScrollView restart ballistic activity out of range', (WidgetTester tester) async { Widget buildScrollView(int n) { return new ScrollView( - children: kStates.take(n).map((String state) { + children: _kStates.take(n).map((String state) { return new Container( height: 200.0, decoration: const BoxDecoration( diff --git a/packages/flutter/test/widgets/states.dart b/packages/flutter/test/widgets/states.dart deleted file mode 100644 index d8839bc08e..0000000000 --- a/packages/flutter/test/widgets/states.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -const List kStates = const [ - 'Alabama', - 'Alaska', - 'Arizona', - 'Arkansas', - 'California', - 'Colorado', - 'Connecticut', - 'Delaware', - 'Florida', - 'Georgia', - 'Hawaii', - 'Idaho', - 'Illinois', - 'Indiana', - 'Iowa', - 'Kansas', - 'Kentucky', - 'Louisiana', - 'Maine', - 'Maryland', - 'Massachusetts', - 'Michigan', - 'Minnesota', - 'Mississippi', - 'Missouri', - 'Montana', - 'Nebraska', - 'Nevada', - 'New Hampshire', - 'New Jersey', - 'New Mexico', - 'New York', - 'North Carolina', - 'North Dakota', - 'Ohio', - 'Oklahoma', - 'Oregon', - 'Pennsylvania', - 'Rhode Island', - 'South Carolina', - 'South Dakota', - 'Tennessee', - 'Texas', - 'Utah', - 'Vermont', - 'Virginia', - 'Washington', - 'West Virginia', - 'Wisconsin', - 'Wyoming', -];