From cbb495c16df463f09961d659fff87cf2fa47ee1f Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Mon, 13 Mar 2017 22:57:05 +0000 Subject: [PATCH] Add more dartdocs for the sliver render objects (#8749) This patch covers multi-box adaptor and the viewports. --- .../flutter/lib/src/rendering/sliver.dart | 6 +- .../rendering/sliver_multi_box_adaptor.dart | 59 ++++++- .../flutter/lib/src/rendering/viewport.dart | 145 +++++++++++++++--- 3 files changed, 177 insertions(+), 33 deletions(-) diff --git a/packages/flutter/lib/src/rendering/sliver.dart b/packages/flutter/lib/src/rendering/sliver.dart index 15e9a3458df..d0ebf3683ef 100644 --- a/packages/flutter/lib/src/rendering/sliver.dart +++ b/packages/flutter/lib/src/rendering/sliver.dart @@ -1225,9 +1225,9 @@ abstract class RenderSliverHelpers implements RenderSliver { /// /// See also: /// -/// - [RenderSliver], which explains more about the Sliver protocol. -/// - [RenderBox], which explains more about the Box protocol. -/// - [RenderViewport], which allows [RenderSliver] objects to be placed inside +/// * [RenderSliver], which explains more about the Sliver protocol. +/// * [RenderBox], which explains more about the Box protocol. +/// * [RenderViewport], which allows [RenderSliver] objects to be placed inside /// a [RenderBox] (the opposite of this class). class RenderSliverToBoxAdapter extends RenderSliver with RenderObjectWithChildMixin, RenderSliverHelpers { /// Creates a [RenderSliver] that wraps a [RenderBox]. 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 d467f6fd364..59d5b0c2cef 100644 --- a/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart +++ b/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart @@ -75,6 +75,17 @@ abstract class RenderSliverBoxChildManager { /// the child list after this function returns. void didAdoptChild(RenderBox child); + /// Called during layout to indicate whether this object provided insufficient + /// children for the [RenderSliverMultiBoxAdaptor] to fill the + /// [SliverConstraints.remainingPaintExtent]. + /// + /// Typically called unconditionally at the start of layout with false and + /// then later called with true when the [RenderSliverMultiBoxAdaptor] + /// fails to create a child required to fill the + /// [SliverConstraints.remainingPaintExtent]. + /// + /// Useful for subclasses to determine whether newly added children could + /// affect the visible contents of the [RenderSliverMultiBoxAdaptor]. void setDidUnderflow(bool value); /// In debug mode, asserts that this manager is not expecting any @@ -88,25 +99,47 @@ abstract class RenderSliverBoxChildManager { bool debugAssertChildListLocked() => true; } +/// Parent data structure used by [RenderSliverMultiBoxAdaptor]. class SliverMultiBoxAdaptorParentData extends SliverLogicalParentData with ContainerParentDataMixin { + /// The index of this child according to the [RenderSliverBoxChildManager]. int index; @override String toString() => 'index=$index; ${super.toString()}'; } -// /// The contract for adding and removing children from this render object is -// /// more strict than for normal render objects: -// /// -// /// - Children can be removed except during a layout pass if they have already -// /// been laid out during that layout pass. -// /// - Children cannot be added except during a call to [childManager], and -// /// then only if there is no child correspending to that index (or the child -// /// child corresponding to that index was first removed). +/// A sliver with multiple box children. +/// +/// [RenderSliverMultiBoxAdaptor] is a base class for slivers that have multiple +/// box children. The children are managed by a [RenderSliverBoxChildManager], +/// which lets subclasses create children lazily during layout. Typically +/// subclasses will create only those children that are actually needed to fill +/// the [SliverConstraints.remainingPaintExtent]. +/// +/// The contract for adding and removing children from this render object is +/// more strict than for normal render objects: +/// +/// * Children can be removed except during a layout pass if they have already +/// been laid out during that layout pass. +/// * Children cannot be added except during a call to [childManager], and +/// then only if there is no child correspending to that index (or the child +/// child corresponding to that index was first removed). +/// +/// See also: +/// +/// * [RenderSliverToBoxAdapter], which has a single box child. +/// * [RenderSliverList], which places its children in a linear +/// array. +/// * [RenderSliverFixedExtentList], which places its children in a linear +/// array with a fixed extent in the main axis. +/// * [RenderSliverGrid], which places its children in arbitrary positions. abstract class RenderSliverMultiBoxAdaptor extends RenderSliver with ContainerRenderObjectMixin, RenderSliverHelpers { + /// Creates a sliver with multiple box children. + /// + /// The [childManager] argument must not be null. RenderSliverMultiBoxAdaptor({ @required RenderSliverBoxChildManager childManager }) : _childManager = childManager { @@ -119,6 +152,12 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver child.parentData = new SliverMultiBoxAdaptorParentData(); } + /// The delegate that manages the children of this object. + /// + /// Rather than having a concrete list of children, a + /// [RenderSliverMultiBoxAdaptor] uses a [RenderSliverBoxChildManager] to + /// create children during layout in order to fill the + /// [SliverConstraints.remainingPaintExtent]. @protected RenderSliverBoxChildManager get childManager => _childManager; final RenderSliverBoxChildManager _childManager; @@ -379,6 +418,10 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver } } + /// Asserts that the reified child list is not empty and has a contiguous + /// sequence of indices. + /// + /// Always returns true. bool debugAssertChildListIsNonEmptyAndContiguous() { assert(() { assert(firstChild != null); diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart index e2a8cedc397..572bea1363f 100644 --- a/packages/flutter/lib/src/rendering/viewport.dart +++ b/packages/flutter/lib/src/rendering/viewport.dart @@ -51,8 +51,6 @@ abstract class RenderAbstractViewport implements RenderObject { double getOffsetToReveal(RenderObject target, double alignment); } -typedef RenderSliver _Advancer(RenderSliver child); - // /// // /// See also: // /// @@ -72,6 +70,11 @@ abstract class RenderViewportBase _axisDirection; AxisDirection _axisDirection; set axisDirection(AxisDirection value) { @@ -82,8 +85,18 @@ abstract class RenderViewportBase axisDirectionToAxis(axisDirection); + /// Which part of the content inside the viewport should be visible. + /// + /// The [ViewportOffset.pixels] value determines the scroll offset that the + /// viewport uses to select which part of its content to display. As the user + /// scrolls the viewport, this value changes, which changes the content that + /// is displayed. ViewportOffset get offset => _offset; ViewportOffset _offset; set offset(ViewportOffset value) { @@ -116,8 +129,38 @@ abstract class RenderViewportBase true; + /// Determines the size and position of some of the children of the viewport. + /// + /// This function is the workhorse of `performLayout` implementations in + /// subclasses. + /// + /// Layout starts with `child`, proceeds according to the `advance` callback, + /// and stops once `advance` returns null. + /// + /// * `scrollOffset` is the [SliverConstraints.scrollOffset] to pass the + /// first child. The scroll offset is adjsted by + /// [SliverGeometry.scrollExtent] for subsequent children. + /// * `overlap` is the [SliverConstraints.overlap] to pass the first child. + /// The overlay is adjusted by the [SliverGeometry.paintOrigin] and + /// [SliverGeometry.paintExtent] for subsequent children. + /// * `layoutOffset` is the layout offset at which to place the first child. + /// The layout offset is updated by the [SliverGeometry.layoutExtent] for + /// subsequent children. + /// * `remainingPaintExtent` is [SliverConstraints.remainingPaintExtent] to + /// pass the first child. The remaining paint extent is updated by the + /// [SliverGeometry.layoutExtent] for subsequent children. + /// * `mainAxisExtent` is the [SliverConstraints.mainAxisExtent] to pass to + /// each child. + /// * `crossAxisExtent` is the [SliverConstraints.crossAxisExtent] to pass to + /// each child. + /// * `growthDirection` is the [SliverConstraints.growthDirection] to pass to + /// each child. + /// + /// Returns the first non-zero [SliverGeometry.scrollOffsetCorrection] + /// encountered, if any. Otherwise returns 0.0. Typical callers will call this + /// function repeatedly until it returns 0.0. @protected - double layoutOneSide( + double layoutChildSequence( RenderSliver child, double scrollOffset, double overlap, @@ -126,7 +169,7 @@ abstract class RenderViewportBase= 0.0); @@ -166,7 +209,7 @@ abstract class RenderViewportBase _anchor; double _anchor; set anchor(double value) { @@ -489,6 +583,13 @@ class RenderViewport extends RenderViewportBase _center; RenderSliver _center; set center(RenderSliver value) { @@ -673,7 +774,7 @@ class RenderViewport extends RenderViewportBase _hasVisualOverflow; @override - void updateOutOfBoundsData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { + void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { switch (growthDirection) { case GrowthDirection.forward: _maxScrollExtent += childLayoutGeometry.scrollExtent; @@ -783,7 +884,7 @@ class RenderViewport extends RenderViewportBase _hasVisualOverflow; @override - void updateOutOfBoundsData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { + void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { assert(growthDirection == GrowthDirection.forward); _maxScrollExtent += childLayoutGeometry.scrollExtent; if (childLayoutGeometry.hasVisualOverflow) @@ -1031,7 +1132,7 @@ class RenderShrinkWrappingViewport extends RenderViewportBase 0; + int get indexOfFirstChild => 0; @override String labelForChild(int index) => 'child $index';