mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Add more dartdocs for the sliver render objects (#8749)
This patch covers multi-box adaptor and the viewports.
This commit is contained in:
parent
cb2b89c389
commit
cbb495c16d
|
@ -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<RenderBox>, RenderSliverHelpers {
|
||||
/// Creates a [RenderSliver] that wraps a [RenderBox].
|
||||
|
|
|
@ -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<RenderBox> {
|
||||
/// 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<RenderBox, SliverMultiBoxAdaptorParentData>,
|
||||
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);
|
||||
|
|
|
@ -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<ParentDataClass extends ContainerParentDataMix
|
|||
assert(offset != null);
|
||||
}
|
||||
|
||||
/// The direction in which the [scrollOffset] increases.
|
||||
///
|
||||
/// For example, if the [axisDirection] is [AxisDirection.down], a scroll
|
||||
/// offset of zero is at the top of the viewport and increases towards the
|
||||
/// bottom of the viewport.
|
||||
AxisDirection get axisDirection => _axisDirection;
|
||||
AxisDirection _axisDirection;
|
||||
set axisDirection(AxisDirection value) {
|
||||
|
@ -82,8 +85,18 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
markNeedsLayout();
|
||||
}
|
||||
|
||||
/// The axis along which the viewport scrolls.
|
||||
///
|
||||
/// For example, if the [axisDirection] is [AxisDirection.down], then the
|
||||
/// [axis] is [Axis.vertical] and the viewport scrolls vertically.
|
||||
Axis get axis => 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<ParentDataClass extends ContainerParentDataMix
|
|||
@override
|
||||
bool get isRepaintBoundary => 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<ParentDataClass extends ContainerParentDataMix
|
|||
double mainAxisExtent,
|
||||
double crossAxisExtent,
|
||||
GrowthDirection growthDirection,
|
||||
_Advancer advance,
|
||||
RenderSliver advance(RenderSliver child),
|
||||
) {
|
||||
assert(scrollOffset.isFinite);
|
||||
assert(scrollOffset >= 0.0);
|
||||
|
@ -166,7 +209,7 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
if (scrollOffset <= 0.0)
|
||||
scrollOffset = 0.0;
|
||||
|
||||
updateOutOfBoundsData(growthDirection, childLayoutGeometry);
|
||||
updateOutOfBandData(growthDirection, childLayoutGeometry);
|
||||
|
||||
// move on to the next child
|
||||
child = advance(child);
|
||||
|
@ -181,14 +224,13 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
if (firstChild == null)
|
||||
return;
|
||||
if (hasVisualOverflow) {
|
||||
context.pushClipRect(needsCompositing, offset, Point.origin & size, paintContents);
|
||||
context.pushClipRect(needsCompositing, offset, Point.origin & size, _paintContents);
|
||||
} else {
|
||||
paintContents(context, offset);
|
||||
_paintContents(context, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@protected
|
||||
void paintContents(PaintingContext context, Offset offset) {
|
||||
void _paintContents(PaintingContext context, Offset offset) {
|
||||
for (RenderSliver child in childrenInPaintOrder) {
|
||||
if (child.geometry.visible)
|
||||
context.paintChild(child, offset + paintOffsetOf(child));
|
||||
|
@ -330,6 +372,14 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
return leadingScrollOffset - (mainAxisExtent - targetMainAxisExtent) * alignment;
|
||||
}
|
||||
|
||||
/// The offset at which the given `child` should be painted.
|
||||
///
|
||||
/// The returned offset is from the top left corner of the inside of the
|
||||
/// viewport to the top left corner of the paint coordinate system of the
|
||||
/// `child`.
|
||||
///
|
||||
/// See also [paintOffsetOf], which uses the layout offset and growth
|
||||
/// direction computed for the child during layout.
|
||||
@protected
|
||||
Offset computeAbsolutePaintOffset(RenderSliver child, double layoutOffset, GrowthDirection growthDirection) {
|
||||
assert(hasSize); // this is only usable once we have a size
|
||||
|
@ -363,7 +413,7 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
String debugDescribeChildren(String prefix) {
|
||||
if (firstChild == null)
|
||||
return '$prefix\n';
|
||||
int count = indexOfFirstChild();
|
||||
int count = indexOfFirstChild;
|
||||
String result = '$prefix \u2502\n';
|
||||
RenderSliver child = firstChild;
|
||||
while (child != lastChild) {
|
||||
|
@ -382,22 +432,52 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
|
||||
// performLayout (and optionally sizedByParent and performResize)
|
||||
|
||||
/// Whether the contents of this viewport would paint outside the bounds of
|
||||
/// the viewport if [paint] did not clip.
|
||||
///
|
||||
/// This property enables an optimization whereby [paint] can skip apply a
|
||||
/// clip of the contents of the viewport are known to paint entirely within
|
||||
/// the bounds of the viewport.
|
||||
@protected
|
||||
bool get hasVisualOverflow;
|
||||
|
||||
/// Called during [layoutChildSequence] for each child.
|
||||
///
|
||||
/// Typically used by subclasses to update any out-of-band data, such as the
|
||||
/// max scroll extent, for each child.
|
||||
@protected
|
||||
void updateOutOfBoundsData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry);
|
||||
void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry);
|
||||
|
||||
/// Called during [layoutChildSequence] to store the layout offset for the
|
||||
/// given child.
|
||||
///
|
||||
/// Different subclasses using different representations for their children's
|
||||
/// layout offset (e.g., logical or physical coordinates). This function lets
|
||||
/// subclasses transform the child's layout offset before storing it in the
|
||||
/// child's parent data.
|
||||
@protected
|
||||
void updateChildLayoutOffset(RenderSliver child, double layoutOffset, GrowthDirection growthDirection);
|
||||
|
||||
/// The offset at which the given `child` should be painted.
|
||||
///
|
||||
/// The returned offset is from the top left corner of the inside of the
|
||||
/// viewport to the top left corner of the paint coordinate system of the
|
||||
/// `child`.
|
||||
///
|
||||
/// See also [computeAbsolutePaintOffset], which computes the paint offset
|
||||
/// from an explict layout offset and growth direction instead of using the
|
||||
/// values computed for the child during layout.
|
||||
@protected
|
||||
Offset paintOffsetOf(RenderSliver child);
|
||||
|
||||
/// Returns the scroll offset within the viewport for the given
|
||||
/// `scrollOffsetWithinChild` within the given `child`.
|
||||
///
|
||||
/// The returned value is an estimate that assumes the slivers within the
|
||||
/// viewport do not change the layout extent in response to changes in their
|
||||
/// scroll offset.
|
||||
@protected
|
||||
double scrollOffsetOf(RenderSliver child, double scrollOffset);
|
||||
|
||||
// applyPaintTransform
|
||||
double scrollOffsetOf(RenderSliver child, double scrollOffsetWithinChild);
|
||||
|
||||
/// Converts the `parentMainAxisPosition` into the child's coordinate system.
|
||||
///
|
||||
|
@ -418,9 +498,16 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||
@protected
|
||||
double computeChildMainAxisPosition(RenderSliver child, double parentMainAxisPosition);
|
||||
|
||||
/// The index of the first child of the viewport relative to the center child.
|
||||
///
|
||||
/// For example, the center child has index zero and the first child in the
|
||||
/// reverse growth direction has index -1.
|
||||
@protected
|
||||
int indexOfFirstChild();
|
||||
int get indexOfFirstChild;
|
||||
|
||||
/// A short string to identify the child with the given index.
|
||||
///
|
||||
/// Used by [debugDescribeChildren] to label the children.
|
||||
@protected
|
||||
String labelForChild(int index);
|
||||
|
||||
|
@ -478,6 +565,13 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
|
|||
child.parentData = new SliverPhysicalContainerParentData();
|
||||
}
|
||||
|
||||
/// The relative position of the zero scroll offset.
|
||||
///
|
||||
/// For example, if [anchor] is 0.5 and the [axisDirection] is
|
||||
/// [AxisDirection.down] or [AxisDirection.up], then the zero scroll offset is
|
||||
/// vertically centered within the viewport. If the [anchor] is 1.0, and the
|
||||
/// [axisDirection] is [AxisDirection.right], then the zero scroll offset is
|
||||
/// on the left edge of the viewport.
|
||||
double get anchor => _anchor;
|
||||
double _anchor;
|
||||
set anchor(double value) {
|
||||
|
@ -489,6 +583,13 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
|
|||
markNeedsLayout();
|
||||
}
|
||||
|
||||
/// The first child in the [GrowthDirection.forward] growth direction.
|
||||
///
|
||||
/// Children after [center] will be placed in the [axisDirection] relative to
|
||||
/// the [center]. Children before [center] will be placed in the opposite of
|
||||
/// the [axisDirection] relative to the [center].
|
||||
///
|
||||
/// The [center] must be a child of the viewport.
|
||||
RenderSliver get center => _center;
|
||||
RenderSliver _center;
|
||||
set center(RenderSliver value) {
|
||||
|
@ -673,7 +774,7 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
|
|||
|
||||
if (leadingNegativeChild != null) {
|
||||
// negative scroll offsets
|
||||
final double result = layoutOneSide(
|
||||
final double result = layoutChildSequence(
|
||||
leadingNegativeChild,
|
||||
math.max(mainAxisExtent, centerOffset) - mainAxisExtent,
|
||||
0.0,
|
||||
|
@ -689,7 +790,7 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
|
|||
}
|
||||
|
||||
// positive scroll offsets
|
||||
return layoutOneSide(
|
||||
return layoutChildSequence(
|
||||
center,
|
||||
math.max(0.0, -centerOffset),
|
||||
leadingNegativeChild == null ? math.min(0.0, -centerOffset) : 0.0,
|
||||
|
@ -706,7 +807,7 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
|
|||
bool get hasVisualOverflow => _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<SliverPhysicalContainerParentDat
|
|||
}
|
||||
|
||||
@override
|
||||
int indexOfFirstChild() {
|
||||
int get indexOfFirstChild {
|
||||
assert(center != null);
|
||||
assert(center.parent == this);
|
||||
assert(firstChild != null);
|
||||
|
@ -954,7 +1055,7 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
|
|||
_maxScrollExtent = 0.0;
|
||||
_shrinkWrapExtent = 0.0;
|
||||
_hasVisualOverflow = false;
|
||||
return layoutOneSide(
|
||||
return layoutChildSequence(
|
||||
firstChild,
|
||||
math.max(0.0, correctedOffset),
|
||||
math.min(0.0, correctedOffset),
|
||||
|
@ -971,7 +1072,7 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
|
|||
bool get hasVisualOverflow => _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<SliverLogicalConta
|
|||
}
|
||||
|
||||
@override
|
||||
int indexOfFirstChild() => 0;
|
||||
int get indexOfFirstChild => 0;
|
||||
|
||||
@override
|
||||
String labelForChild(int index) => 'child $index';
|
||||
|
|
Loading…
Reference in a new issue