Commit 830d163c authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add more dartdocs for slivers (#9164)

This patch adds docs for many of the sliver widgets.
parent 5d8bad74
...@@ -211,8 +211,8 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda ...@@ -211,8 +211,8 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
} }
} }
/// A sliver that contains multiple box children that have a given extent in the /// A sliver that places multiple box children with the same main axis extent in
/// main axis. /// a linear array.
/// ///
/// [RenderSliverFixedExtentList] places its children in a linear array along /// [RenderSliverFixedExtentList] places its children in a linear array along
/// the main axis starting at offset zero and without gaps. Each child is forced /// the main axis starting at offset zero and without gaps. Each child is forced
......
...@@ -424,8 +424,7 @@ class SliverGridParentData extends SliverMultiBoxAdaptorParentData { ...@@ -424,8 +424,7 @@ class SliverGridParentData extends SliverMultiBoxAdaptorParentData {
String toString() => 'crossAxisOffset=$crossAxisOffset; ${super.toString()}'; String toString() => 'crossAxisOffset=$crossAxisOffset; ${super.toString()}';
} }
/// A sliver that contains multiple box children that whose size and position /// A sliver that places multiple box children in a two dimensional arrangement.
/// are determined by a delegate.
/// ///
/// [RenderSliverGrid] places its children in arbitrary positions determined by /// [RenderSliverGrid] places its children in arbitrary positions determined by
/// [gridDelegate]. Each child is forced to have the size specified by the /// [gridDelegate]. Each child is forced to have the size specified by the
......
...@@ -24,8 +24,9 @@ import 'sliver_multi_box_adaptor.dart'; ...@@ -24,8 +24,9 @@ import 'sliver_multi_box_adaptor.dart';
/// ///
/// If the children have a fixed extent in the main axis, consider using /// If the children have a fixed extent in the main axis, consider using
/// [RenderSliverFixedExtentList] rather than [RenderSliverList] because /// [RenderSliverFixedExtentList] rather than [RenderSliverList] because
/// does not need to perform layout on its children to obtain their extent in /// [RenderSliverFixedExtentList] does not need to perform layout on its
/// the main axis and is therefore more efficient. /// children to obtain their extent in the main axis and is therefore more
/// efficient.
/// ///
/// See also: /// See also:
/// ///
......
...@@ -68,8 +68,7 @@ abstract class ScrollView extends StatelessWidget { ...@@ -68,8 +68,7 @@ abstract class ScrollView extends StatelessWidget {
/// Defaults to [Axis.vertical]. /// Defaults to [Axis.vertical].
final Axis scrollDirection; final Axis scrollDirection;
/// Whether the scroll view scrolls in the reading direction in the /// Whether the scroll view scrolls in the reading direction.
/// [scrollDirection].
/// ///
/// For example, if the reading direction is left-to-right and /// For example, if the reading direction is left-to-right and
/// [scrollDirection] is [Axis.horizontal], then the scroll view scrolls from /// [scrollDirection] is [Axis.horizontal], then the scroll view scrolls from
......
...@@ -38,6 +38,7 @@ import 'scrollable.dart'; ...@@ -38,6 +38,7 @@ import 'scrollable.dart';
/// * [PageView], for a scrollable that works page by page. /// * [PageView], for a scrollable that works page by page.
/// * [Scrollable], which handles arbitrary scrolling effects. /// * [Scrollable], which handles arbitrary scrolling effects.
class SingleChildScrollView extends StatelessWidget { class SingleChildScrollView extends StatelessWidget {
/// Creates a box in which a single widget can be scrolled.
SingleChildScrollView({ SingleChildScrollView({
Key key, Key key,
this.scrollDirection: Axis.vertical, this.scrollDirection: Axis.vertical,
...@@ -57,12 +58,32 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -57,12 +58,32 @@ class SingleChildScrollView extends StatelessWidget {
); );
} }
/// The axis along which the scroll view scrolls.
///
/// Defaults to [Axis.vertical].
final Axis scrollDirection; final Axis scrollDirection;
/// Whether the scroll view scrolls in the reading direction.
///
/// For example, if the reading direction is left-to-right and
/// [scrollDirection] is [Axis.horizontal], then the scroll view scrolls from
/// left to right when [reverse] is false and from right to left when
/// [reverse] is true.
///
/// Similarly, if [scrollDirection] is [Axis.vertical], then scroll view
/// scrolls from top to bottom when [reverse] is false and from bottom to top
/// when [reverse] is true.
///
/// Defaults to false.
final bool reverse; final bool reverse;
/// The amount of space by which to inset the child.
final EdgeInsets padding; final EdgeInsets padding;
/// An object that can be used to control the position to which this scroll
/// view is scrolled.
///
/// Must be null if [primary] is true.
final ScrollController controller; final ScrollController controller;
/// Whether this is the primary scroll view associated with the parent /// Whether this is the primary scroll view associated with the parent
...@@ -75,8 +96,15 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -75,8 +96,15 @@ class SingleChildScrollView extends StatelessWidget {
/// not specified. /// not specified.
final bool primary; final bool primary;
/// How the scroll view should respond to user input.
///
/// For example, determines how the scroll view continues to animate after the
/// user stops dragging the scroll view.
///
/// Defaults to matching platform conventions.
final ScrollPhysics physics; final ScrollPhysics physics;
/// The widget that scrolls.
final Widget child; final Widget child;
AxisDirection _getDirection(BuildContext context) { AxisDirection _getDirection(BuildContext context) {
......
...@@ -15,11 +15,35 @@ export 'package:flutter/rendering.dart' show ...@@ -15,11 +15,35 @@ export 'package:flutter/rendering.dart' show
SliverGridDelegateWithFixedCrossAxisCount, SliverGridDelegateWithFixedCrossAxisCount,
SliverGridDelegateWithMaxCrossAxisExtent; SliverGridDelegateWithMaxCrossAxisExtent;
/// A delegate that supplies children for slivers.
///
/// Many slivers lazily construct their box children to avoid creating more
/// children than are visible through the [Viewport]. Rather than receiving
/// their children as an explicit [List], they receive their children using a
/// [SliverChildDelegate].
///
/// It's uncommon to subclass [SliverChildDelegate]. Instead, consider using one
/// of the existing subclasses that provide adaptors to builder callbacks or
/// explict child lists.
///
/// See also:
///
/// * [SliverChildBuilderDelegate], which is a delegate that uses a builder
/// callback to construct the children.
/// * [SliverChildListDelegate], which is a delegate that has an explicit list
/// of children.
abstract class SliverChildDelegate { abstract class SliverChildDelegate {
/// Abstract const constructor. This constructor enables subclasses to provide /// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions. /// const constructors so that they can be used in const expressions.
const SliverChildDelegate(); const SliverChildDelegate();
/// Returns the child with the given index.
///
/// Should return null if asked to build a widget with a greater index than
/// exists.
///
/// Subclasses typically override this function and wrap their children in
/// [RepaintBoundary] widgets.
Widget build(BuildContext context, int index); Widget build(BuildContext context, int index);
/// Returns an estimate of the number of children this delegate will build. /// Returns an estimate of the number of children this delegate will build.
...@@ -55,6 +79,15 @@ abstract class SliverChildDelegate { ...@@ -55,6 +79,15 @@ abstract class SliverChildDelegate {
/// the underlying render tree. /// the underlying render tree.
void didFinishLayout(int firstIndex, int lastIndex) {} void didFinishLayout(int firstIndex, int lastIndex) {}
/// Called whenever a new instance of the child delegate class is
/// provided to the sliver.
///
/// If the new instance represents different information than the old
/// instance, then the method should return true, otherwise it should return
/// false.
///
/// If the method returns false, then the [build] call might be optimized
/// away.
bool shouldRebuild(covariant SliverChildDelegate oldDelegate); bool shouldRebuild(covariant SliverChildDelegate oldDelegate);
@override @override
...@@ -64,7 +97,9 @@ abstract class SliverChildDelegate { ...@@ -64,7 +97,9 @@ abstract class SliverChildDelegate {
return '$runtimeType#$hashCode(${description.join(", ")})'; return '$runtimeType#$hashCode(${description.join(", ")})';
} }
/// Add additional information to the given description for use by [toString].
@protected @protected
@mustCallSuper
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
try { try {
final int children = estimatedChildCount; final int children = estimatedChildCount;
...@@ -76,11 +111,38 @@ abstract class SliverChildDelegate { ...@@ -76,11 +111,38 @@ abstract class SliverChildDelegate {
} }
} }
/// A delegate that supplies children for slivers using a builder callback.
///
/// Many slivers lazily construct their box children to avoid creating more
/// children than are visible through the [Viewport]. This delegate provides
/// children using an [IndexedWidgetBuilder] callback. The widgets returned from
/// the builder callback are wrapped in [RepaintBoundary] widgets.
///
/// See also:
///
/// * [SliverChildListDelegate], which is a delegate that has an explicit list
/// of children.
class SliverChildBuilderDelegate extends SliverChildDelegate { class SliverChildBuilderDelegate extends SliverChildDelegate {
/// Creates a delegate that supplies children for slivers using the given
/// builder callback
const SliverChildBuilderDelegate(this.builder, { this.childCount }); const SliverChildBuilderDelegate(this.builder, { this.childCount });
/// Called to build children for the sliver.
///
/// Will be called only for indices greater than or equal to zero and less
/// than [childCount] (if [childCount] is non-null).
///
/// Should return null if asked to build a widget with a greater index than
/// exists.
///
/// The delegate wraps the children returned by this builder in
/// [RepaintBoundary] widgets.
final IndexedWidgetBuilder builder; final IndexedWidgetBuilder builder;
/// The total number of children this delegate can provide.
///
/// If null, the number of children is determined by the least index for which
/// [builder] returns null.
final int childCount; final int childCount;
@override @override
...@@ -101,19 +163,33 @@ class SliverChildBuilderDelegate extends SliverChildDelegate { ...@@ -101,19 +163,33 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
bool shouldRebuild(covariant SliverChildBuilderDelegate oldDelegate) => true; bool shouldRebuild(covariant SliverChildBuilderDelegate oldDelegate) => true;
} }
// /// /// A delegate that supplies children for slivers using an explicit list.
// /// In general building all the widgets in advance is not efficient. It is ///
// /// better to create a delegate that builds them on demand by subclassing /// Many slivers lazily construct their box children to avoid creating more
// /// [SliverChildDelegate] directly. /// children than are visible through the [Viewport]. This delegate provides
// /// /// children using an explicit list, which is convenient but reduces the benefit
// /// This class is provided for the cases where either the list of children is /// of building children lazily.
// /// known well in advance (ideally the children are themselves compile-time ///
// /// constants, for example), and therefore will not be built each time the /// In general building all the widgets in advance is not efficient. It is
// /// delegate itself is created, or the list is small, such that it's likely /// better to create a delegate that builds them on demand using
// /// always visible (and thus there is nothing to be gained by building it on /// [SliverChildBuilderDelegate] or by subclassing [SliverChildDelegate]
// /// demand). For example, the body of a dialog box might fit both of these /// directly.
// /// conditions. ///
/// This class is provided for the cases where either the list of children is
/// known well in advance (ideally the children are themselves compile-time
/// constants, for example), and therefore will not be built each time the
/// delegate itself is created, or the list is small, such that it's likely
/// always visible (and thus there is nothing to be gained by building it on
/// demand). For example, the body of a dialog box might fit both of these
/// conditions.
///
/// See also:
///
/// * [SliverChildBuilderDelegate], which is a delegate that uses a builder
/// callback to construct the children.
class SliverChildListDelegate extends SliverChildDelegate { class SliverChildListDelegate extends SliverChildDelegate {
/// Creates a delegate that supplies children for slivers using the given
/// list.
const SliverChildListDelegate(this.children, { this.addRepaintBoundaries: true }); const SliverChildListDelegate(this.children, { this.addRepaintBoundaries: true });
/// Whether to wrap each child in a [RepaintBoundary]. /// Whether to wrap each child in a [RepaintBoundary].
...@@ -149,7 +225,11 @@ class SliverChildListDelegate extends SliverChildDelegate { ...@@ -149,7 +225,11 @@ class SliverChildListDelegate extends SliverChildDelegate {
} }
} }
/// A base class for sliver that have multiple box children.
///
/// Helps subclasses build their children lazily using a [SliverChildDelegate].
abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget {
/// Initializes fields for subclasses.
SliverMultiBoxAdaptorWidget({ SliverMultiBoxAdaptorWidget({
Key key, Key key,
@required this.delegate, @required this.delegate,
...@@ -157,6 +237,16 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { ...@@ -157,6 +237,16 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget {
assert(delegate != null); assert(delegate != null);
} }
/// The delegate that provides the children for this widget.
///
/// The children are constructed lazily using this widget to avoid creating
/// more children than are visible through the [Viewport].
///
/// See also:
///
/// * [SliverChildBuilderDelegate] and [SliverChildListDelegate], which are
/// commonly used subclasses of [SliverChildDelegate] that use a builder
/// callback and an explicit child list, respectively.
final SliverChildDelegate delegate; final SliverChildDelegate delegate;
@override @override
...@@ -165,6 +255,13 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { ...@@ -165,6 +255,13 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget {
@override @override
RenderSliverMultiBoxAdaptor createRenderObject(BuildContext context); RenderSliverMultiBoxAdaptor createRenderObject(BuildContext context);
/// Returns an estimate of the max scroll extent for all the children.
///
/// Subclasses should override this function if they have additional
/// information about their max scroll extent.
///
/// The default implementation returns calls
/// [SliverChildDelegate.estimateMaxScrollOffset].
double estimateMaxScrollOffset( double estimateMaxScrollOffset(
SliverConstraints constraints, SliverConstraints constraints,
int firstIndex, int firstIndex,
...@@ -188,7 +285,29 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget { ...@@ -188,7 +285,29 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget {
} }
} }
/// A sliver that places multiple box children in a linear array along the main
/// axis.
///
/// Each child is forced to have the [SliverConstraints.crossAxisExtent] in the
/// cross axis but determines its own main axis extent.
///
/// [SliverList] determines its scroll offset by "dead reckoning" because
/// children outside the visible part of the sliver are not materialized, which
/// means [SliverList] cannot learn their main axis extent. Instead, newly
/// materialized children are placed adjacent to existing children.
///
/// If the children have a fixed extent in the main axis, consider using
/// [SliverFixedExtentList] rather than [SliverList] because
/// [SliverFixedExtentList] does not need to perform layout on its children to
/// obtain their extent in the main axis and is therefore more efficient.
///
/// See also:
///
/// * [SliverFixedExtentList], which is more efficient for children with
/// the same extent in the main axis.
/// * [SliverGrid], which places its children in arbitrary positions.
class SliverList extends SliverMultiBoxAdaptorWidget { class SliverList extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver that places box children in a linear array.
SliverList({ SliverList({
Key key, Key key,
@required SliverChildDelegate delegate, @required SliverChildDelegate delegate,
...@@ -201,13 +320,34 @@ class SliverList extends SliverMultiBoxAdaptorWidget { ...@@ -201,13 +320,34 @@ class SliverList extends SliverMultiBoxAdaptorWidget {
} }
} }
/// A sliver that places multiple box children with the same main axis extent in
/// a linear array.
///
/// [SliverFixedExtentList] places its children in a linear array along the main
/// axis starting at offset zero and without gaps. Each child is forced to have
/// the [itemExtent] in the main axis and the
/// [SliverConstraints.crossAxisExtent] in the cross axis.
///
/// [SliverFixedExtentList] is more efficient than [SliverList] because
/// [SliverFixedExtentList] does not need to perform layout on its children to
/// obtain their extent in the main axis.
///
/// See also:
///
/// * [SliverFill], which determines the [itemExtent] based on
/// [SliverConstraints.viewportMainAxisExtent].
/// * [SliverList], which does not require its children to have the same
/// extent in the main axis.
class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget { class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver that places box children with the same main axis extent
/// in a linear array.
SliverFixedExtentList({ SliverFixedExtentList({
Key key, Key key,
@required SliverChildDelegate delegate, @required SliverChildDelegate delegate,
@required this.itemExtent, @required this.itemExtent,
}) : super(key: key, delegate: delegate); }) : super(key: key, delegate: delegate);
/// The extent the children are forced to have in the main axis.
final double itemExtent; final double itemExtent;
@override @override
...@@ -222,13 +362,27 @@ class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget { ...@@ -222,13 +362,27 @@ class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget {
} }
} }
/// A sliver that places multiple box children in a two dimensional arrangement.
///
/// [SliverGrid] places its children in arbitrary positions determined by
/// [gridDelegate]. Each child is forced to have the size specified by the
/// [gridDelegate].
///
/// See also:
///
/// * [SliverList], which places its children in a linear array.
/// * [SliverFixedExtentList], which places its children in a linear
/// array with a fixed extent in the main axis.
class SliverGrid extends SliverMultiBoxAdaptorWidget { class SliverGrid extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver that places multiple box children in a two dimensional
/// arrangement.
SliverGrid({ SliverGrid({
Key key, Key key,
@required SliverChildDelegate delegate, @required SliverChildDelegate delegate,
@required this.gridDelegate, @required this.gridDelegate,
}) : super(key: key, delegate: delegate); }) : super(key: key, delegate: delegate);
/// The delegate that controls the size and position of the children.
final SliverGridDelegate gridDelegate; final SliverGridDelegate gridDelegate;
@override @override
...@@ -260,7 +414,18 @@ class SliverGrid extends SliverMultiBoxAdaptorWidget { ...@@ -260,7 +414,18 @@ class SliverGrid extends SliverMultiBoxAdaptorWidget {
} }
} }
/// A sliver that contains a multiple box children that each fill the viewport.
///
/// [SliverFill] places its children in a linear array along the main axis. Each
/// child is sized to fill the viewport, both in the main and cross axis.
///
/// See also:
///
/// * [SliverFixedExtentList], which has a configurable [itemExtent].
/// * [SliverList], which does not require its children to have the same
/// extent in the main axis.
class SliverFill extends SliverMultiBoxAdaptorWidget { class SliverFill extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver whose box children that each fill the viewport.
SliverFill({ SliverFill({
Key key, Key key,
@required SliverChildDelegate delegate, @required SliverChildDelegate delegate,
...@@ -270,6 +435,11 @@ class SliverFill extends SliverMultiBoxAdaptorWidget { ...@@ -270,6 +435,11 @@ class SliverFill extends SliverMultiBoxAdaptorWidget {
assert(viewportFraction > 0.0); assert(viewportFraction > 0.0);
} }
/// The fraction of the viewport that each child should fill in the main axis.
///
/// If this fraction is less than 1.0, more than one child will be visible at
/// once. If this fraction is greater than 1.0, each child will be larger than
/// the viewport in the main axis.
final double viewportFraction; final double viewportFraction;
@override @override
...@@ -284,7 +454,12 @@ class SliverFill extends SliverMultiBoxAdaptorWidget { ...@@ -284,7 +454,12 @@ class SliverFill extends SliverMultiBoxAdaptorWidget {
} }
} }
/// An element that lazily builds children for a [SliverMultiBoxAdaptorWidget].
///
/// Implements [RenderSliverBoxChildManager], which lets this element manage
/// the children of subclasses of [RenderSliverMultiBoxAdaptor].
class SliverMultiBoxAdaptorElement extends RenderObjectElement implements RenderSliverBoxChildManager { class SliverMultiBoxAdaptorElement extends RenderObjectElement implements RenderSliverBoxChildManager {
/// Creates an element that lazily builds children for the given widget.
SliverMultiBoxAdaptorElement(SliverMultiBoxAdaptorWidget widget) : super(widget); SliverMultiBoxAdaptorElement(SliverMultiBoxAdaptorWidget widget) : super(widget);
@override @override
......
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