diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart index db4e8a7f4e..dbf97716da 100644 --- a/packages/flutter/lib/src/rendering/box.dart +++ b/packages/flutter/lib/src/rendering/box.dart @@ -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 diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart index 21422740a6..7d2d0d58a3 100644 --- a/packages/flutter/lib/src/rendering/viewport.dart +++ b/packages/flutter/lib/src/rendering/viewport.dart @@ -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; diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index aac00dfe1a..0edfbcce01 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -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; diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 6681c834a3..0f4cc3ea8f 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -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) { } diff --git a/packages/flutter/lib/src/widgets/lazy_block.dart b/packages/flutter/lib/src/widgets/lazy_block.dart index 09bed22097..cfa11793a6 100644 --- a/packages/flutter/lib/src/widgets/lazy_block.dart +++ b/packages/flutter/lib/src/widgets/lazy_block.dart @@ -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. diff --git a/packages/flutter/lib/src/widgets/pageable_list.dart b/packages/flutter/lib/src/widgets/pageable_list.dart index f1a1ef4bca..b572554add 100644 --- a/packages/flutter/lib/src/widgets/pageable_list.dart +++ b/packages/flutter/lib/src/widgets/pageable_list.dart @@ -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. /// diff --git a/packages/flutter/lib/src/widgets/scroll_configuration.dart b/packages/flutter/lib/src/widgets/scroll_configuration.dart index 3434e4b6b8..ed54658f73 100644 --- a/packages/flutter/lib/src/widgets/scroll_configuration.dart +++ b/packages/flutter/lib/src/widgets/scroll_configuration.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '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; diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 4ae59cfa2f..47ef5be23d 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -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 [], @@ -839,6 +875,7 @@ class Block extends StatelessWidget { assert(!children.any((Widget child) => child == null)); } + /// The children, all of which are materialized. final List 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. diff --git a/packages/flutter/lib/src/widgets/scrollable_grid.dart b/packages/flutter/lib/src/widgets/scrollable_grid.dart index 9539eda4c8..9a355baaa8 100644 --- a/packages/flutter/lib/src/widgets/scrollable_grid.dart +++ b/packages/flutter/lib/src/widgets/scrollable_grid.dart @@ -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 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 children; - // TODO(abarth): Support horizontal grids. - Axis get mainAxis => Axis.vertical; - @override RenderGrid createRenderObject(BuildContext context) => new RenderGrid(delegate: delegate); diff --git a/packages/flutter/lib/src/widgets/scrollable_list.dart b/packages/flutter/lib/src/widgets/scrollable_list.dart index 9f9f68bc18..28dca198b7 100644 --- a/packages/flutter/lib/src/widgets/scrollable_list.dart +++ b/packages/flutter/lib/src/widgets/scrollable_list.dart @@ -4,15 +4,37 @@ import 'dart:math' as math; +import 'package:flutter/rendering.dart'; +import 'package:meta/meta.dart'; + import 'clamp_overscrolls.dart'; import 'framework.dart'; import 'scroll_configuration.dart'; import 'scrollable.dart'; import 'virtual_viewport.dart'; -import 'package:flutter/rendering.dart'; - +/// A scrollable list of children that have equal size. +/// +/// [ScrollableList] differs from [ScrollableLazyList] in that [ScrollableList] +/// uses an [Iterable] list of children. That makes [ScrollableList] suitable +/// for a large (but not extremely large or infinite) list of children. +/// +/// [ScrollableList] differs from [LazyBlock] in that [ScrollableList] requires +/// each of its children to be the same size. That makes [ScrollableList] more +/// efficient but less flexible than [LazyBlock]. +/// +/// Prefer [ScrollableViewport] when there is only one child. +/// +/// See also: +/// +/// * [ScrollableLazyList] +/// * [LazyBlock] +/// * [ScrollableViewport] class ScrollableList extends StatelessWidget { + /// Creats a scrollable list of children that have equal size. + /// + /// The [scrollDirection], [scrollAnchor], and [itemExtent] arguments must not + /// be null. ScrollableList({ Key key, this.initialScrollOffset, @@ -23,11 +45,13 @@ class ScrollableList extends StatelessWidget { this.onScrollEnd, this.snapOffsetCallback, this.scrollableKey, - this.itemExtent, + @required this.itemExtent, this.itemsWrap: false, this.padding, this.children }) : super(key: key) { + assert(scrollDirection != null); + assert(scrollAnchor != null); assert(itemExtent != null); } @@ -93,12 +117,13 @@ class ScrollableList extends StatelessWidget { /// The height of each item if [scrollDirection] is Axis.vertical, otherwise the width of each item. final double itemExtent; + /// Whether the first item should be revealed after scrolling past the last item. final bool itemsWrap; /// The amount of space by which to inset the children inside the viewport. final EdgeInsets padding; - /// The axis along which this widget should scroll. + /// The children, some of which might be materialized. final Iterable children; Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) { @@ -148,15 +173,51 @@ class _VirtualListViewport extends VirtualViewport { this.padding ) { assert(mainAxis != null); + assert(anchor != null); assert(itemExtent != null); } + /// Called when the interior or exterior dimensions of the viewport change. final ExtentsChangedCallback onExtentsChanged; + + /// The [startOffset] without taking the [padding] into account. final double scrollOffset; + + /// 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 + /// child at the end of the container, when the viewport has not been offset. + /// + /// For example, if the [mainAxis] 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 viewport 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 + /// viewport, 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 anchor; + + /// The height of each item if [scrollDirection] is Axis.vertical, otherwise the width of each item. final double itemExtent; + + /// Whether the first item should be revealed after scrolling past the last item. final bool itemsWrap; + + /// The amount of space by which to inset the children inside the viewport. final EdgeInsets padding; double get _leadingPadding { @@ -298,13 +359,35 @@ class _VirtualListViewportElement extends VirtualViewportElement { } } +/// A virtual viewport onto a list of equally sized children. +/// +/// [ListViewport] differs from [LazyListViewport] in that [ListViewport] +/// uses an [Iterable] list of children. That makes [ListViewport] suitable +/// for a large (but not extremely large or infinite) list of children. +/// +/// [ListViewport] differs from [LazyBlockViewport] in that [ListViewport] +/// requires each of its children to be the same size. That makes [ListViewport] +/// more efficient but less flexible than [LazyBlockViewport]. +/// +/// Prefer [Viewport] when there is only one child. +/// +/// Used by [ScrollableList]. +/// +/// See also: +/// +/// * [LazyListViewport] +/// * [LazyBlockViewport] +/// * [GridViewport] class ListViewport extends _VirtualListViewport with VirtualViewportFromIterable { + /// Creates a virtual viewport onto a list of equally sized children. + /// + /// The [mainAxis], [anchor], and [itemExtent] arguments must not be null. ListViewport({ ExtentsChangedCallback onExtentsChanged, double scrollOffset: 0.0, Axis mainAxis: Axis.vertical, ViewportAnchor anchor: ViewportAnchor.start, - double itemExtent, + @required double itemExtent, bool itemsWrap: false, EdgeInsets padding, this.children @@ -322,12 +405,27 @@ class ListViewport extends _VirtualListViewport with VirtualViewportFromIterable final Iterable children; } -/// An optimized scrollable widget for a large number of children that are all -/// the same size (extent) in the scrollDirection. For example for -/// ScrollDirection.vertical itemExtent is the height of each item. Use this -/// widget when you have a large number of children or when you are concerned -/// about offscreen widgets consuming resources. +/// An infinite scrollable list of children that have equal size. +/// +/// [ScrollableLazyList] differs from [ScrollableList] in that +/// [ScrollableLazyList] uses an [ItemListBuilder] to lazily create children. +/// That makes [ScrollableLazyList] suitable for an extremely large or infinite +/// list of children but also makes it more verbose than [ScrollableList]. +/// +/// [ScrollableLazyList] differs from [LazyBlock] in that [ScrollableLazyList] +/// requires each of its children to be the same size. That makes +/// [ScrollableLazyList] more efficient but less flexible than [LazyBlock]. +/// +/// See also: +/// +/// * [ScrollableList] +/// * [LazyBlock] class ScrollableLazyList extends StatelessWidget { + /// Creates an infinite scrollable list of children that have equal size. + /// + /// The [scrollDirection], [scrollAnchor], [itemExtent], and [itemBuilder] + /// arguments must not be null. The [itemCount] argument must not be null + /// unless the [scrollAnchor] argument is [ViewportAnchor.start]. ScrollableLazyList({ Key key, this.initialScrollOffset, @@ -338,9 +436,9 @@ class ScrollableLazyList extends StatelessWidget { this.onScrollEnd, this.snapOffsetCallback, this.scrollableKey, - this.itemExtent, + @required this.itemExtent, this.itemCount, - this.itemBuilder, + @required this.itemBuilder, this.padding }) : super(key: key) { assert(itemExtent != null); @@ -412,9 +510,21 @@ class ScrollableLazyList extends StatelessWidget { /// The total number of list items. final int itemCount; + /// Returns a widget representing the item with the given index. + /// + /// This function might be called with index parameters in any order. This + /// function should return null for indices that exceed the number of children + /// (i.e., [itemCount] if non-null). If this function must not return a null + /// value for an index if it previously returned a non-null value for that + /// index or a larger index. + /// + /// This function might be called during the build or layout phases of the + /// pipeline. + /// + /// The returned widget might or might not be cached by [ScrollableLazyList]. final ItemListBuilder itemBuilder; - /// The insets for the entire list. + /// The amount of space by which to inset the children inside the viewport. final EdgeInsets padding; Widget _buildViewport(BuildContext context, ScrollableState state, double scrollOffset) { @@ -451,16 +561,38 @@ class ScrollableLazyList extends StatelessWidget { } } +/// A virtual viewport onto an extremely large or infinite list of equally sized children. +/// +/// [LazyListViewport] differs from [ListViewport] in that [LazyListViewport] +/// uses an [ItemListBuilder] to lazily create children. That makes +/// [LazyListViewport] suitable for an extremely large or infinite list of +/// children but also makes it more verbose than [ListViewport]. +/// +/// [LazyListViewport] differs from [LazyBlockViewport] in that +/// [LazyListViewport] requires each of its children to be the same size. That +/// makes [LazyListViewport] more efficient but less flexible than +/// [LazyBlockViewport]. +/// +/// Used by [ScrollableLazyList]. +/// +/// See also: +/// +/// * [ListViewport] +/// * [LazyBlockViewport] class LazyListViewport extends _VirtualListViewport with VirtualViewportFromBuilder { + /// Creates a virtual viewport onto an extremely large or infinite list of equally sized children. + /// + /// The [mainAxis], [anchor], [itemExtent], and [itemBuilder] arguments must + /// not be null. LazyListViewport({ ExtentsChangedCallback onExtentsChanged, double scrollOffset: 0.0, Axis mainAxis: Axis.vertical, ViewportAnchor anchor: ViewportAnchor.start, - double itemExtent, + @required double itemExtent, EdgeInsets padding, this.itemCount, - this.itemBuilder + @required this.itemBuilder }) : super( onExtentsChanged, scrollOffset, @@ -469,7 +601,9 @@ class LazyListViewport extends _VirtualListViewport with VirtualViewportFromBuil itemExtent, false, // Don't support wrapping yet. padding - ); + ) { + assert(itemBuilder != null); + } @override final int itemCount; diff --git a/packages/flutter/lib/src/widgets/semantics_debugger.dart b/packages/flutter/lib/src/widgets/semantics_debugger.dart index 0fd8bcf182..9596d50f7e 100644 --- a/packages/flutter/lib/src/widgets/semantics_debugger.dart +++ b/packages/flutter/lib/src/widgets/semantics_debugger.dart @@ -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. diff --git a/packages/flutter/lib/src/widgets/status_transitions.dart b/packages/flutter/lib/src/widgets/status_transitions.dart index d2a19613e9..38e5bdb68d 100644 --- a/packages/flutter/lib/src/widgets/status_transitions.dart +++ b/packages/flutter/lib/src/widgets/status_transitions.dart @@ -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 animation; + /// Override this function to build widgets that depend on the current status + /// of the animation. Widget build(BuildContext context); @override diff --git a/packages/flutter/lib/src/widgets/table.dart b/packages/flutter/lib/src/widgets/table.dart index 6a4c2d769e..720dc8ae5c 100644 --- a/packages/flutter/lib/src/widgets/table.dart +++ b/packages/flutter/lib/src/widgets/table.dart @@ -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 children; @override @@ -53,11 +69,15 @@ class _TableElementRow { final List 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 children: const [], @@ -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 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 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 _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 { + /// 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 diff --git a/packages/flutter/lib/src/widgets/title.dart b/packages/flutter/lib/src/widgets/title.dart index 2e5fbc4ab1..3f5ac1daba 100644 --- a/packages/flutter/lib/src/widgets/title.dart +++ b/packages/flutter/lib/src/widgets/title.dart @@ -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); } diff --git a/packages/flutter/lib/src/widgets/transitions.dart b/packages/flutter/lib/src/widgets/transitions.dart index 39df4838f3..1f0b41f050 100644 --- a/packages/flutter/lib/src/widgets/transitions.dart +++ b/packages/flutter/lib/src/widgets/transitions.dart @@ -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 animation, - this.builder, + @required Animation animation, + @required this.builder, this.child }) : super(key: key, animation: animation) { assert(builder != null); diff --git a/packages/flutter/lib/src/widgets/virtual_viewport.dart b/packages/flutter/lib/src/widgets/virtual_viewport.dart index b7b1333a91..2342db5aee 100644 --- a/packages/flutter/lib/src/widgets/virtual_viewport.dart +++ b/packages/flutter/lib/src/widgets/virtual_viewport.dart @@ -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;