Commit 313c17fa authored by Adam Barth's avatar Adam Barth

Complete dartdoc for scrollable widgets (#4415)

parent 43d35cb2
......@@ -186,11 +186,11 @@ class BoxConstraints extends Constraints {
}
/// Returns box constraints with the same width constraints but with
/// unconstrainted height.
/// unconstrained height.
BoxConstraints widthConstraints() => new BoxConstraints(minWidth: minWidth, maxWidth: maxWidth);
/// Returns box constraints with the same height constraints but with
/// unconstrainted width
/// unconstrained width
BoxConstraints heightConstraints() => new BoxConstraints(minHeight: minHeight, maxHeight: maxHeight);
/// Returns the width that both satisfies the constraints and is as close as
......
......@@ -125,9 +125,9 @@ class RenderViewportBase extends RenderBox {
markNeedsSemanticsUpdate();
}
/// The direction in which the child is permitted to be larger than the viewport
/// The direction in which the child is permitted to be larger than the viewport.
///
/// The child is given layout constraints that are fully unconstrainted along
/// The child is given layout constraints that are fully unconstrained along
/// the main axis (e.g., the child can be as tall as it wants if the main axis
/// is vertical).
Axis get mainAxis => _mainAxis;
......
......@@ -1307,9 +1307,9 @@ class Viewport extends SingleChildRenderObjectWidget {
/// The offset can be non-zero only in the [mainAxis].
final Offset paintOffset;
/// The direction in which the child is permitted to be larger than the viewport
/// The direction in which the child is permitted to be larger than the viewport.
///
/// The child is given layout constraints that are fully unconstrainted along
/// The child is given layout constraints that are fully unconstrained along
/// the main axis (e.g., the child can be as tall as it wants if the main axis
/// is vertical).
final Axis mainAxis;
......
......@@ -582,18 +582,18 @@ abstract class InheritedWidget extends _ProxyWidget {
abstract class RenderObjectWidget extends Widget {
const RenderObjectWidget({ Key key }) : super(key: key);
/// RenderObjectWidgets always inflate to a RenderObjectElement subclass.
/// RenderObjectWidgets always inflate to a [RenderObjectElement] subclass.
@override
RenderObjectElement createElement();
/// Creates an instance of the RenderObject class that this
/// RenderObjectWidget represents, using the configuration described by this
/// RenderObjectWidget.
/// Creates an instance of the [RenderObject] class that this
/// [RenderObjectWidget] represents, using the configuration described by this
/// [RenderObjectWidget].
RenderObject createRenderObject(BuildContext context);
/// Copies the configuration described by this RenderObjectWidget to the given
/// RenderObject, which must be of the same type as returned by this class'
/// createRenderObject(BuildContext context).
/// Copies the configuration described by this [RenderObjectWidget] to the
/// given [RenderObject], which will be of the same type as returned by this
/// object's [createRenderObject].
void updateRenderObject(BuildContext context, RenderObject renderObject) { }
void didUnmountRenderObject(RenderObject renderObject) { }
......
......@@ -112,7 +112,7 @@ class LazyBlockChildren extends LazyBlockDelegate {
}
}
/// An infinite scrolling list of variable height children.
/// An infinite scrolling list of variably-sized children.
///
/// [LazyBlock] is a general-purpose scrollable list for a large (or infinite)
/// number of children that might not all have the same height. Rather than
......@@ -130,7 +130,7 @@ class LazyBlockChildren extends LazyBlockDelegate {
/// [scrollOffset] is expensive because [LazyBlock] computes the size of every
/// child between the old scroll offset and the new scroll offset.
///
/// Prefer [ScrollableList] when all the children have the same height because
/// Prefer [ScrollableList] when all the children have the same size because
/// it can use that property to be more efficient. Prefer [ScrollableViewport]
/// when there is only one child.
class LazyBlock extends StatelessWidget {
......@@ -297,11 +297,11 @@ class LazyBlockViewport extends RenderObjectWidget {
/// horizontal viewports, the offset is from the left of the viewport.
final double startOffset;
/// The direction in which the children are permitted to be larger than the viewport
/// The direction in which the children are permitted to be larger than the viewport.
///
/// The children are given layout constraints that are fully unconstrainted
/// along the main axis (e.g., children can be as tall as it wants if the main
/// axis is vertical).
/// The children are given layout constraints that are fully unconstrained
/// along the main axis (e.g., children can be as tall as they want if the
/// main axis is vertical).
final Axis mainAxis;
/// The amount of space by which to inset the children inside the viewport.
......
......@@ -382,7 +382,11 @@ class _VirtualPageViewport extends VirtualViewport {
@override
final double startOffset;
/// The axis along which the viewport is bigger on the inside than the outside.
/// The direction in which the children are permitted to be larger than the viewport.
///
/// The children are given layout constraints that are fully unconstrained
/// along the main axis (e.g., children can be as tall as they want if the
/// main axis is vertical).
final Axis mainAxis;
/// Whether to place first child at the start of the container or the last
......@@ -555,7 +559,7 @@ class PageViewport extends _VirtualPageViewport with VirtualViewportFromIterable
/// [LazyPageViewport] differs from [PageViewport] in that [LazyPageViewport]
/// uses an [ItemListBuilder] to lazily create children. That makes
/// [LazyPageViewport] suitable for an extremely large or infinite list of
/// children but alos makes it more verbose than [PageViewport].
/// children but also makes it more verbose than [PageViewport].
class LazyPageViewport extends _VirtualPageViewport with VirtualViewportFromBuilder {
/// Creates a virtual viewport that displays a single child at a time.
///
......
......@@ -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 'package:meta/meta.dart';
import 'framework.dart';
import 'scroll_behavior.dart';
......@@ -36,13 +38,18 @@ class ScrollConfigurationDelegate {
/// [ScrollableList], [ScrollableLazyList]. The [Scrollable] base class uses
/// [ScrollConfiguration] to create its [ScrollBehavior].
class ScrollConfiguration extends InheritedWidget {
/// Creates a widget that controls descendant [Scrollable] widgets.
///
/// If the [delegate] argument is null, the scroll configuration for this
/// subtree is controlled by the default implementation of
/// [ScrollConfigurationDelegate].
ScrollConfiguration({
Key key,
this.delegate,
Widget child
@required Widget child
}) : super(key: key, child: child);
static final ScrollConfigurationDelegate _defaultDelegate = const ScrollConfigurationDelegate();
static const ScrollConfigurationDelegate _defaultDelegate = const ScrollConfigurationDelegate();
/// Defines the ScrollBehavior and scrollable wrapper for descendants.
final ScrollConfigurationDelegate delegate;
......
......@@ -26,8 +26,17 @@ final Tolerance kPixelScrollTolerance = new Tolerance(
distance: 1.0 / ui.window.devicePixelRatio // logical pixels
);
/// Signature for building a widget based on [ScrollableState].
typedef Widget ScrollBuilder(BuildContext context, ScrollableState state);
/// Signature for callbacks that receive a scroll offset.
///
/// Used by [Scrollable.onScrollStart], [Scrollable.onScroll], and [Scrollable.onScrollEnd].
typedef void ScrollListener(double scrollOffset);
/// Signature for determining the offset at which scrolling should snap.
///
/// Used by [Scrollable.snapOffsetCallback].
typedef double SnapOffsetCallback(double scrollOffset, Size containerSize);
/// A base class for scrollable widgets.
......@@ -117,6 +126,9 @@ class Scrollable extends StatefulWidget {
/// then it is as if the callback was null.
final SnapOffsetCallback snapOffsetCallback;
/// Using to build the content of this widget.
///
/// See [buildContent] for details.
final ScrollBuilder builder;
/// The state from the closest instance of this class that encloses the given context.
......@@ -692,18 +704,31 @@ enum ScrollNotificationKind {
/// Indicates that a descendant scrollable has scrolled.
class ScrollNotification extends Notification {
/// Creates a notification about scrolling.
ScrollNotification(this.scrollable, this.kind);
// Indicates if we're at the start, end or the middle of a scroll.
/// Indicates if we're at the start, middle, or end of a scroll.
final ScrollNotificationKind kind;
/// The scrollable that scrolled.
final ScrollableState scrollable;
}
/// A simple scrolling widget that has a single child. Use this widget if
/// you are not worried about offscreen widgets consuming resources.
/// A simple scrolling widget that has a single child.
///
/// Use this widget if you are not worried about offscreen widgets consuming
/// resources.
///
/// See also:
///
/// * [ScrollableList]
/// * [PageableList]
/// * [ScrollableGrid]
/// * [LazyBlock]
class ScrollableViewport extends StatelessWidget {
/// Creates a simple scrolling widget that has a single child.
///
/// The [scrollDirection] and [scrollAnchor] arguments must not be null.
ScrollableViewport({
Key key,
this.initialScrollOffset,
......@@ -715,7 +740,10 @@ class ScrollableViewport extends StatelessWidget {
this.snapOffsetCallback,
this.scrollableKey,
this.child
}) : super(key: key);
}) : super(key: key) {
assert(scrollDirection != null);
assert(scrollAnchor != null);
}
// Warning: keep the dartdoc comments that follow in sync with the copies in
// Scrollable, LazyBlock, ScrollableLazyList, ScrollableList, and
......@@ -815,14 +843,22 @@ class ScrollableViewport extends StatelessWidget {
}
}
/// A mashup of [ScrollableViewport] and [BlockBody]. Useful when you have a small,
/// fixed number of children that you wish to arrange in a block layout and that
/// might exceed the height of its container (and therefore need to scroll).
/// A mashup of [ScrollableViewport] and [BlockBody].
///
/// Useful when you have a small, fixed number of children that you wish to
/// arrange in a block layout and that might exceed the height of its container
/// (and therefore need to scroll).
///
/// If you have a large number of children, consider using [LazyBlock] (if the
/// children have variable height) or [ScrollableList] (if the children all have
/// the same fixed height).
///
/// See also:
///
/// * [ScrollableList]
/// * [LazyBlock]
class Block extends StatelessWidget {
/// Creates a scrollable array of children.
Block({
Key key,
this.children: const <Widget>[],
......@@ -839,6 +875,7 @@ class Block extends StatelessWidget {
assert(!children.any((Widget child) => child == null));
}
/// The children, all of which are materialized.
final List<Widget> children;
/// The amount of space by which to inset the children inside the viewport.
......@@ -847,7 +884,29 @@ class Block extends StatelessWidget {
/// The scroll offset this widget should use when first created.
final double initialScrollOffset;
/// The axis along which this widget should scroll.
final Axis scrollDirection;
/// Whether to place first child at the start of the container or
/// the last child at the end of the container, when the scrollable
/// has not been scrolled and has no initial scroll offset.
///
/// For example, if the [scrollDirection] is [Axis.vertical] and
/// there are enough items to overflow the container, then
/// [ViewportAnchor.start] means that the top of the first item
/// should be aligned with the top of the scrollable with the last
/// item below the bottom, and [ViewportAnchor.end] means the bottom
/// of the last item should be aligned with the bottom of the
/// scrollable, with the first item above the top.
///
/// This also affects whether, when an item is added or removed, the
/// displacement will be towards the first item or the last item.
/// Continuing the earlier example, if a new item is inserted in the
/// middle of the list, in the [ViewportAnchor.start] case the items
/// after it (with greater indices, down to the item with the
/// highest index) will be pushed down, while in the
/// [ViewportAnchor.end] case the items before it (with lower
/// indices, up to the item with the index 0) will be pushed up.
final ViewportAnchor scrollAnchor;
/// Called whenever this widget starts to scroll.
......
......@@ -6,6 +6,7 @@ import 'dart:math' as math;
import 'package:collection/collection.dart' show lowerBound;
import 'package:flutter/rendering.dart';
import 'package:meta/meta.dart';
import 'clamp_overscrolls.dart';
import 'framework.dart';
......@@ -15,8 +16,17 @@ import 'virtual_viewport.dart';
/// A vertically scrollable grid.
///
/// Requires that delegate places its children in row-major order.
/// Requires that [delegate] places its children in row-major order.
///
/// See also:
///
/// * [CustomGrid]
/// * [ScrollableList]
/// * [ScrollableViewport]
class ScrollableGrid extends StatelessWidget {
/// Creates a vertically scrollable grid.
///
/// The [delegate] argument must not be null.
ScrollableGrid({
Key key,
this.initialScrollOffset,
......@@ -25,9 +35,11 @@ class ScrollableGrid extends StatelessWidget {
this.onScrollEnd,
this.snapOffsetCallback,
this.scrollableKey,
this.delegate,
@required this.delegate,
this.children
}) : super(key: key);
}) : super(key: key) {
assert(delegate != null);
}
// Warning: keep the dartdoc comments that follow in sync with the copies in
// Scrollable, LazyBlock, ScrollableViewport, ScrollableList, and
......@@ -63,7 +75,10 @@ class ScrollableGrid extends StatelessWidget {
/// The key for the Scrollable created by this widget.
final Key scrollableKey;
/// The delegate that controls the layout of the children.
final GridDelegate delegate;
/// The children that will be placed in the grid.
final Iterable<Widget> children;
Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) {
......@@ -98,25 +113,39 @@ class ScrollableGrid extends StatelessWidget {
}
}
/// A virtual viewport onto a grid of widgets.
///
/// Used by [ScrollableGrid].
///
/// See also:
///
/// * [ListViewport]
/// * [LazyListViewport]
class GridViewport extends VirtualViewportFromIterable {
/// Creates a virtual viewport onto a grid of widgets.
///
/// The [delegate] argument must not be null.
GridViewport({
this.startOffset,
this.delegate,
this.onExtentsChanged,
this.children
});
}) {
assert(delegate != null);
}
@override
final double startOffset;
/// The delegate that controls the layout of the children.
final GridDelegate delegate;
/// Called when the interior or exterior dimensions of the viewport change.
final ExtentsChangedCallback onExtentsChanged;
@override
final Iterable<Widget> children;
// TODO(abarth): Support horizontal grids.
Axis get mainAxis => Axis.vertical;
@override
RenderGrid createRenderObject(BuildContext context) => new RenderGrid(delegate: delegate);
......
......@@ -11,11 +11,14 @@ import 'basic.dart';
import 'framework.dart';
import 'gesture_detector.dart';
/// Visualizes the semantics for the child.
/// A widget that visualizes the semantics for the child.
///
/// This widget is useful for understand how an app presents itself to
/// accessibility technology.
class SemanticsDebugger extends StatefulWidget {
/// Creates a widget that visualizes the semantics for the child.
///
/// The [child] argument must not be null.
const SemanticsDebugger({ Key key, this.child }) : super(key: key);
/// The widget below this widget in the tree.
......
......@@ -2,14 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:meta/meta.dart';
import 'basic.dart';
import 'framework.dart';
/// A widget that rebuilds when the given animation changes status.
abstract class StatusTransitionWidget extends StatefulWidget {
/// Initializes fields for subclasses.
///
/// The [animation] argument must not be null.
StatusTransitionWidget({
Key key,
this.animation
@required this.animation
}) : super(key: key) {
assert(animation != null);
}
......@@ -17,6 +22,8 @@ abstract class StatusTransitionWidget extends StatefulWidget {
/// The animation to which this widget is listening.
final Animation<double> animation;
/// Override this function to build widgets that depend on the current status
/// of the animation.
Widget build(BuildContext context);
@override
......
......@@ -21,10 +21,26 @@ export 'package:flutter/rendering.dart' show
TableCellVerticalAlignment,
TableColumnWidth;
/// A horizontal group of cells in a [Table].
class TableRow {
/// Creates a row in a [Table].
const TableRow({ this.key, this.decoration, this.children });
/// An identifier for the row.
final LocalKey key;
/// A decoration to paint behind this row.
///
/// Row decorations fill the horizontal and vertical extent of each row in
/// the table, unlike decorations for individual cells, which might not fill
/// either.
final Decoration decoration;
/// The widgets that comprise the cells in this row.
///
/// Children may be wrapped in [TableCell] widgets to provide per-cell
/// configuration to the [Table], but children are not required to be wrapped
/// in [TableCell] widgets.
final List<Widget> children;
@override
......@@ -53,11 +69,15 @@ class _TableElementRow {
final List<Element> children;
}
/// Uses the table layout algorithm for its children.
/// A widget that uses the table layout algorithm for its children.
///
/// For details about the table layout algorithm, see [RenderTable].
/// To control the alignment of children, see [TableCell].
class Table extends RenderObjectWidget {
/// Creates a table.
///
/// The [children], [defaultColumnWidth], and [defaultVerticalAlignment]
/// arguments must not be null.
Table({
Key key,
List<TableRow> children: const <TableRow>[],
......@@ -82,11 +102,33 @@ class Table extends RenderObjectWidget {
assert(!children.any((TableRow row1) => row1.key != null && children.any((TableRow row2) => row1 != row2 && row1.key == row2.key)));
}
/// The rows of the table.
final List<TableRow> children;
/// How the horizontal extents of the columns of this table should be determined.
///
/// If the [Map] has a null entry for a given column, the table uses the
/// [defaultColumnWidth] instead.
///
/// The layout performance of the table depends critically on which column
/// sizing algorithms are used here. In particular, [IntrinsicColumnWidth] is
/// quite expensive because it needs to measure each cell in the column to
/// determine the intrinsic size of the column.
final Map<int, TableColumnWidth> columnWidths;
/// How to determine with widths of columns that don't have an explicit sizing algorithm.
///
/// Specifically, the [defaultColumnWidth] is used for column `i` if
/// `columnWidths[i]` is null.
final TableColumnWidth defaultColumnWidth;
/// The style to use when painting the boundary and interior divisions of the table.
final TableBorder border;
/// How cells that do not explicitly specify a vertical alignment are aligned vertically.
final TableCellVerticalAlignment defaultVerticalAlignment;
/// The text baseline to use when aligning rows using [TableCellVerticalAlignment.baseline].
final TextBaseline textBaseline;
final List<Decoration> _rowDecorations;
......@@ -239,13 +281,21 @@ class _TableElement extends RenderObjectElement {
}
}
/// A widget that controls how a child of a [Table] is aligned.
///
/// A [TableCell] widget must be a descendant of a [Table], and the path from
/// the [TableCell] widget to its enclosing [Table] must contain only
/// [TableRow]s, [StatelessWidget]s, or [StatefulWidget]s (not
/// other kinds of widgets, like [RenderObjectWidget]s).
class TableCell extends ParentDataWidget<Table> {
/// Creates a widget that controls how a child of a [Table] is aligned.
TableCell({
Key key,
this.verticalAlignment,
@required Widget child
}) : super(key: key, child: child);
/// How this cell is aligned vertically.
final TableCellVerticalAlignment verticalAlignment;
@override
......
......@@ -5,13 +5,14 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
/// Controls the description of this app in the operating system.
/// A widget that describes this app in the operating system.
class Title extends StatelessWidget {
/// Creates a widget that describes this app to the operating system.
Title({
Key key,
this.title,
this.child,
this.color
this.color,
this.child
}) : super(key: key) {
assert(color == null || color.alpha == 0xFF);
}
......
......@@ -4,6 +4,7 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
import 'package:vector_math/vector_math_64.dart' show Matrix4;
import 'basic.dart';
......@@ -19,10 +20,12 @@ export 'package:flutter/rendering.dart' show RelativeRect;
/// For more complex case involving additional state, consider using
/// [AnimatedBuilder].
abstract class AnimatedWidget extends StatefulWidget {
/// Creates a widget that rebuilds when the given animation changes value.
///
/// The [animation] argument is required.
AnimatedWidget({
Key key,
this.animation
@required this.animation
}) : super(key: key) {
assert(animation != null);
}
......@@ -342,11 +345,11 @@ typedef Widget TransitionBuilder(BuildContext context, Widget child);
class AnimatedBuilder extends AnimatedWidget {
/// Creates an animated builder.
///
/// The [animation] argument is required.
/// The [animation] and [builder] arguments must not be null.
AnimatedBuilder({
Key key,
Animation<Object> animation,
this.builder,
@required Animation<Object> animation,
@required this.builder,
this.child
}) : super(key: key, animation: animation) {
assert(builder != null);
......
......@@ -4,12 +4,13 @@
import 'dart:math' as math;
import 'package:flutter/rendering.dart';
import 'package:meta/meta.dart';
import 'basic.dart';
import 'debug.dart';
import 'framework.dart';
import 'package:flutter/rendering.dart';
/// Signature for reporting the interior and exterior dimensions of a viewport.
///
/// * The [contentExtent] is the interior dimension of the viewport (i.e., the
......@@ -34,12 +35,15 @@ abstract class _WidgetProvider {
Widget getChild(int i);
}
/// Materializes a contiguous subset of its children.
/// An element that materializes a contiguous subset of its children.
///
/// This class is a building block for building a widget that has more children
/// than it wishes to display at any given time. For example, [ScrollableList]
/// uses this element to materialize only those children that are visible.
abstract class VirtualViewportElement extends RenderObjectElement {
/// Creates an element that materializes a contiguous subset of its children.
///
/// The [widget] argument must not be null.
VirtualViewportElement(VirtualViewport widget) : super(widget);
@override
......@@ -123,6 +127,9 @@ abstract class VirtualViewportElement extends RenderObjectElement {
renderObject.paintOffset = scrollOffsetToPixelDelta(widget.startOffset - startOffsetBase);
}
/// Copies the configuration described by [widget] to this element's [renderObject].
@protected
@mustCallSuper
void updateRenderObject(VirtualViewport oldWidget) {
renderObject.virtualChildCount = _widgetProvider.virtualChildCount;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment