Commit f182b978 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add more scrolling dartdocs (#8763)

Also, add a few other random dartdocs that I encountered along the way.
parent 1e63dc4a
...@@ -9,9 +9,37 @@ import 'box.dart'; ...@@ -9,9 +9,37 @@ import 'box.dart';
import 'sliver.dart'; import 'sliver.dart';
import 'sliver_multi_box_adaptor.dart'; import 'sliver_multi_box_adaptor.dart';
/// 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.
///
/// [RenderSliverList] determines its scroll offset by "dead reckoning" because
/// children outside the visible part of the sliver are not materialized, which
/// means [RenderSliverList] cannot learn their main axis extent. Instead, newly
/// materialized children are placed adjacent to existing children. If this dead
/// reckoning results in a logical inconsistency (e.g., attempting to place the
/// zeroth child at a scroll offset other than zero), the [RenderSliverList]
/// generates a [SliverGeometry.scrollOffsetCorrection] to restore consistency.
///
/// If the children have a fixed extent in the main axis, consider using
/// [RenderSliverFixedExtentList] rather than [RenderSliverList] because
/// does not need to perform layout on its children to obtain their extent in
/// the main axis and is therefore more efficient.
///
/// See also:
///
/// * [RenderSliverFixedExtentList], which is more efficient for children with
/// the same extent in the main axis.
/// * [RenderSliverGrid], which places its children in arbitrary positions.
class RenderSliverList extends RenderSliverMultiBoxAdaptor { class RenderSliverList extends RenderSliverMultiBoxAdaptor {
/// Creates a sliver that places multiple box children in a linear array along
/// the main axis.
///
/// The [childManager] argument must not be null.
RenderSliverList({ RenderSliverList({
@required RenderSliverBoxChildManager childManager @required RenderSliverBoxChildManager childManager,
}) : super(childManager: childManager); }) : super(childManager: childManager);
@override @override
......
...@@ -20,7 +20,7 @@ import 'sliver.dart'; ...@@ -20,7 +20,7 @@ import 'sliver.dart';
/// its child. Any incoming [SliverConstraints.overlap] is ignored and not /// its child. Any incoming [SliverConstraints.overlap] is ignored and not
/// passed on to the child. /// passed on to the child.
/// ///
/// Applying this to anything but the most mundane sliver is likely to have /// Applying padding to anything but the most mundane sliver is likely to have
/// undesired effects. For example, wrapping a /// undesired effects. For example, wrapping a
/// [RenderSliverPinnedPersistentHeader] will cause the app bar to overlap /// [RenderSliverPinnedPersistentHeader] will cause the app bar to overlap
/// earlier slivers (contrary to the normal behavior of pinned app bars), and /// earlier slivers (contrary to the normal behavior of pinned app bars), and
......
...@@ -50,9 +50,35 @@ ScrollDirection flipScrollDirection(ScrollDirection direction) { ...@@ -50,9 +50,35 @@ ScrollDirection flipScrollDirection(ScrollDirection direction) {
return null; return null;
} }
/// Which part of the content inside the viewport should be visible.
///
/// The [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.
///
/// This object notifies its listeners when [pixels] changes.
///
/// See also:
///
/// * [ScrollPosition], which is a commonly used concrete subclass.
/// * [RenderViewportBase], which is a render object that uses viewport
/// offsets.
abstract class ViewportOffset extends ChangeNotifier { abstract class ViewportOffset extends ChangeNotifier {
/// Default constructor.
///
/// Allows subclasses to construct this object directly.
ViewportOffset(); ViewportOffset();
/// Creates a viewport offset with the given [pixels] value.
///
/// The [pixels] value does not change unless the viewport issues a
/// correction.
factory ViewportOffset.fixed(double value) = _FixedViewportOffset; factory ViewportOffset.fixed(double value) = _FixedViewportOffset;
/// Creates a viewport offset with a [pixels] value of 0.0.
///
/// The [pixels] value does not change unless the viewport issues a
/// correction.
factory ViewportOffset.zero() = _FixedViewportOffset.zero; factory ViewportOffset.zero() = _FixedViewportOffset.zero;
/// The number of pixels to offset the children in the opposite of the axis direction. /// The number of pixels to offset the children in the opposite of the axis direction.
...@@ -61,6 +87,9 @@ abstract class ViewportOffset extends ChangeNotifier { ...@@ -61,6 +87,9 @@ abstract class ViewportOffset extends ChangeNotifier {
/// represents the number of logical pixels to move the children _up_ the /// represents the number of logical pixels to move the children _up_ the
/// screen. Similarly, if the axis direction is left, then the pixels value /// screen. Similarly, if the axis direction is left, then the pixels value
/// represents the number of logical pixesl to move the children to _right_. /// represents the number of logical pixesl to move the children to _right_.
///
/// This object notifies its listeners when this value changes (except when
/// the value changes due to [correctBy]).
double get pixels; double get pixels;
/// Called when the viewport's extents are established. /// Called when the viewport's extents are established.
...@@ -139,6 +168,15 @@ abstract class ViewportOffset extends ChangeNotifier { ...@@ -139,6 +168,15 @@ abstract class ViewportOffset extends ChangeNotifier {
return '$runtimeType(${description.join(", ")})'; return '$runtimeType(${description.join(", ")})';
} }
/// Add additional information to the given description for use by [toString].
///
/// This method makes it easier for subclasses to coordinate to provide a
/// high-quality [toString] implementation. The [toString] implementation on
/// the [State] base class calls [debugFillDescription] to collect useful
/// information from subclasses to incorporate into its return value.
///
/// If you override this, make sure to start your method with a call to
/// `super.debugFillDescription(description)`.
@mustCallSuper @mustCallSuper
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
description.add('offset: ${pixels?.toStringAsFixed(1)}'); description.add('offset: ${pixels?.toStringAsFixed(1)}');
......
...@@ -268,6 +268,9 @@ class Ticker { ...@@ -268,6 +268,9 @@ class Ticker {
unscheduleTick(); unscheduleTick();
} }
/// An optional label can be provided for debugging purposes.
///
/// This label will appear in the [toString] output in debug builds.
final String debugLabel; final String debugLabel;
StackTrace _debugCreationStack; StackTrace _debugCreationStack;
......
...@@ -45,9 +45,9 @@ abstract class StreamBuilderBase<T, S> extends StatefulWidget { ...@@ -45,9 +45,9 @@ abstract class StreamBuilderBase<T, S> extends StatefulWidget {
StreamBuilderBase({ Key key, this.stream }) : super(key: key); StreamBuilderBase({ Key key, this.stream }) : super(key: key);
/// The asynchronous computation to which this builder is currently connected, /// The asynchronous computation to which this builder is currently connected,
/// possibly `null`. When changed, the current summary is updated using /// possibly null. When changed, the current summary is updated using
/// [afterDisconnecting], if the previous stream was not `null`, followed by /// [afterDisconnecting], if the previous stream was not null, followed by
/// [afterConnecting], if the new stream is not `null`. /// [afterConnecting], if the new stream is not null.
final Stream<T> stream; final Stream<T> stream;
/// Returns the initial summary of stream interaction, typically representing /// Returns the initial summary of stream interaction, typically representing
...@@ -189,7 +189,7 @@ class AsyncSnapshot<T> { ...@@ -189,7 +189,7 @@ class AsyncSnapshot<T> {
assert(data == null || error == null); assert(data == null || error == null);
} }
/// Creates an [AsyncSnapshot] in [ConnectionState.none] with `null` data and error. /// Creates an [AsyncSnapshot] in [ConnectionState.none] with null data and error.
AsyncSnapshot.nothing() : this._(ConnectionState.none, null, null); AsyncSnapshot.nothing() : this._(ConnectionState.none, null, null);
/// Creates an [AsyncSnapshot] in the specified [state] and with the specified [data]. /// Creates an [AsyncSnapshot] in the specified [state] and with the specified [data].
...@@ -201,7 +201,7 @@ class AsyncSnapshot<T> { ...@@ -201,7 +201,7 @@ class AsyncSnapshot<T> {
/// Current state of connection to the asynchronous computation. /// Current state of connection to the asynchronous computation.
final ConnectionState connectionState; final ConnectionState connectionState;
/// Latest data received. Is `null`, if [error] is not. /// Latest data received. Is null, if [error] is not.
final T data; final T data;
/// Returns latest data received, failing if there is no data. /// Returns latest data received, failing if there is no data.
...@@ -216,16 +216,16 @@ class AsyncSnapshot<T> { ...@@ -216,16 +216,16 @@ class AsyncSnapshot<T> {
throw new StateError('Snapshot has neither data nor error'); throw new StateError('Snapshot has neither data nor error');
} }
/// Latest error object received. Is `null`, if [data] is not. /// Latest error object received. Is null, if [data] is not.
final Object error; final Object error;
/// Returns a snapshot like this one, but in the specified [state]. /// Returns a snapshot like this one, but in the specified [state].
AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error); AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error);
/// Returns whether this snapshot contains a non-`null` data value. /// Returns whether this snapshot contains a non-null data value.
bool get hasData => data != null; bool get hasData => data != null;
/// Returns whether this snapshot contains a non-`null` error value. /// Returns whether this snapshot contains a non-null error value.
bool get hasError => error != null; bool get hasError => error != null;
@override @override
...@@ -288,8 +288,8 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap ...@@ -288,8 +288,8 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap
/// * `new AsyncSnapshot<int>(ConnectionState.none, 5, null)` /// * `new AsyncSnapshot<int>(ConnectionState.none, 5, null)`
/// * `new AsyncSnapshot<int>(ConnectionState.waiting, 5, null)` /// * `new AsyncSnapshot<int>(ConnectionState.waiting, 5, null)`
/// ///
/// The latter will be produced only when the new stream is non-`null`. The former /// The latter will be produced only when the new stream is non-null. The former
/// only when the old stream is non-`null`. /// only when the old stream is non-null.
/// ///
/// The stream may produce errors, resulting in snapshots of the form /// The stream may produce errors, resulting in snapshots of the form
/// ///
...@@ -314,7 +314,7 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> { ...@@ -314,7 +314,7 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
assert(builder != null); assert(builder != null);
} }
/// The build strategy currently used by this builder. Cannot be `null`. /// The build strategy currently used by this builder. Cannot be null.
final AsyncWidgetBuilder<T> builder; final AsyncWidgetBuilder<T> builder;
@override @override
...@@ -374,12 +374,16 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> { ...@@ -374,12 +374,16 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
/// * `new AsyncSnapshot<String>(ConnectionState.waiting, 'some data', null)` /// * `new AsyncSnapshot<String>(ConnectionState.waiting, 'some data', null)`
/// ///
/// In general, the latter will be produced only when the new future is /// In general, the latter will be produced only when the new future is
/// non-`null`. The former only when the old future is non-`null`. /// non-null. The former only when the old future is non-null.
/// ///
/// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with /// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with
/// `future?.asStream()`, except that snapshots with `ConnectionState.active` /// `future?.asStream()`, except that snapshots with `ConnectionState.active`
/// may appear for the latter, depending on how the stream is implemented. /// may appear for the latter, depending on how the stream is implemented.
class FutureBuilder<T> extends StatefulWidget { class FutureBuilder<T> extends StatefulWidget {
/// Creates a widget that builds itself based on the latest snapshot of
/// interaction with a [Future].
///
/// The [builder] must not be null.
FutureBuilder({ FutureBuilder({
Key key, Key key,
this.future, this.future,
...@@ -389,10 +393,10 @@ class FutureBuilder<T> extends StatefulWidget { ...@@ -389,10 +393,10 @@ class FutureBuilder<T> extends StatefulWidget {
} }
/// The asynchronous computation to which this builder is currently connected, /// The asynchronous computation to which this builder is currently connected,
/// possibly `null`. /// possibly null.
final Future<T> future; final Future<T> future;
/// The build strategy currently used by this builder. Cannot be `null`. /// The build strategy currently used by this builder. Cannot be null.
final AsyncWidgetBuilder<T> builder; final AsyncWidgetBuilder<T> builder;
@override @override
......
...@@ -60,8 +60,14 @@ class BannerPainter extends CustomPainter { ...@@ -60,8 +60,14 @@ class BannerPainter extends CustomPainter {
/// Where to show the banner (e.g., the upper right corder). /// Where to show the banner (e.g., the upper right corder).
final BannerLocation location; final BannerLocation location;
/// The color to paint behind the [message].
///
/// Defaults to a dark red.
final Color color; final Color color;
/// The text style to use for the [message].
///
/// Defaults to bold, white text.
final TextStyle textStyle; final TextStyle textStyle;
bool _prepared = false; bool _prepared = false;
......
...@@ -1478,7 +1478,28 @@ class Baseline extends SingleChildRenderObjectWidget { ...@@ -1478,7 +1478,28 @@ class Baseline extends SingleChildRenderObjectWidget {
// SLIVERS // SLIVERS
/// A sliver that contains a single box widget.
///
/// Slivers are special-purpose widgets that can be combined using a
/// [CustomScrollView] to create custom scroll effects. A [SliverToBoxAdapter]
/// is a basic sliver that creates a bridge back to one of the usual box-based
/// widgets.
///
/// Rather than using multiple [SliverToBoxAdapter] widgets to display multiple
/// box widgets in a [CustomScrollView], consider using [SliverList],
/// [SliverFixedExtentList], or [SliverGrid], which are more efficient because
/// they instantiate only those children that are actually visible through the
/// scroll view's viewport.
///
/// See also:
///
/// * [CustomScrollView], which displays a scrollable list of slivers.
/// * [SliverList], which displays multiple box widgets in a linear array.
/// * [SliverFixedExtentList], which displays multiple box widgets with the
/// same main-axis extent in a linear array.
/// * [SliverGrid], which displays multiple box widgets in arbitrary positions.
class SliverToBoxAdapter extends SingleChildRenderObjectWidget { class SliverToBoxAdapter extends SingleChildRenderObjectWidget {
/// Creates a sliver that contains a single box widget.
SliverToBoxAdapter({ SliverToBoxAdapter({
Key key, Key key,
Widget child, Widget child,
...@@ -1488,7 +1509,26 @@ class SliverToBoxAdapter extends SingleChildRenderObjectWidget { ...@@ -1488,7 +1509,26 @@ class SliverToBoxAdapter extends SingleChildRenderObjectWidget {
RenderSliverToBoxAdapter createRenderObject(BuildContext context) => new RenderSliverToBoxAdapter(); RenderSliverToBoxAdapter createRenderObject(BuildContext context) => new RenderSliverToBoxAdapter();
} }
/// A sliver that applies padding on each side of another sliver.
///
/// Slivers are special-purpose widgets that can be combined using a
/// [CustomScrollView] to create custom scroll effects. A [SliverPadding]
/// is a basic sliver that insets another sliver by applying padding on each
/// side.
///
/// Applying padding to anything but the most mundane sliver is likely to have
/// undesired effects. For example, wrapping a
/// [SliverPinnedPersistentHeader] will cause the app bar to overlap
/// earlier slivers (contrary to the normal behavior of pinned app bars), and
/// while the app bar is pinned, the padding will scroll away.
///
/// See also:
///
/// * [CustomScrollView], which displays a scrollable list of slivers.
class SliverPadding extends SingleChildRenderObjectWidget { class SliverPadding extends SingleChildRenderObjectWidget {
/// Creates a sliver that applies padding on each side of another sliver.
///
/// The [padding] argument must not be null.
SliverPadding({ SliverPadding({
Key key, Key key,
@required this.padding, @required this.padding,
...@@ -1497,6 +1537,7 @@ class SliverPadding extends SingleChildRenderObjectWidget { ...@@ -1497,6 +1537,7 @@ class SliverPadding extends SingleChildRenderObjectWidget {
assert(padding != null); assert(padding != null);
} }
/// The amount of space by which to inset the child sliver.
final EdgeInsets padding; final EdgeInsets padding;
@override @override
......
...@@ -62,6 +62,12 @@ class Form extends StatefulWidget { ...@@ -62,6 +62,12 @@ class Form extends StatefulWidget {
FormState createState() => new FormState(); FormState createState() => new FormState();
} }
/// State assocated with a [Form] widget.
///
/// A [FormState] object can ve used to [save], [reset], and [validate] every
/// [FormField] that is a descendant of the associated [Form].
///
/// Typically obtained via [Form.of].
class FormState extends State<Form> { class FormState extends State<Form> {
int _generation = 0; int _generation = 0;
Set<FormFieldState<dynamic>> _fields = new Set<FormFieldState<dynamic>>(); Set<FormFieldState<dynamic>> _fields = new Set<FormFieldState<dynamic>>();
...@@ -163,9 +169,10 @@ typedef void FormFieldSetter<T>(T newValue); ...@@ -163,9 +169,10 @@ typedef void FormFieldSetter<T>(T newValue);
/// Used by [FormField.builder]. /// Used by [FormField.builder].
typedef Widget FormFieldBuilder<T>(FormFieldState<T> field); typedef Widget FormFieldBuilder<T>(FormFieldState<T> field);
/// A single form field. This widget maintains the current state of the form /// A single form field.
/// field, so that updates and validation errors are visually reflected in the ///
/// UI. /// This widget maintains the current state of the form field, so that updates
/// and validation errors are visually reflected in the UI.
/// ///
/// When used inside a [Form], you can use methods on [FormState] to query or /// When used inside a [Form], you can use methods on [FormState] to query or
/// manipulate the form data as a whole. For example, calling [FormState.save] /// manipulate the form data as a whole. For example, calling [FormState.save]
...@@ -184,6 +191,9 @@ typedef Widget FormFieldBuilder<T>(FormFieldState<T> field); ...@@ -184,6 +191,9 @@ typedef Widget FormFieldBuilder<T>(FormFieldState<T> field);
/// * [Form], which is the widget that aggregates the form fields. /// * [Form], which is the widget that aggregates the form fields.
/// * [TextField], which is a commonly used form field for entering text. /// * [TextField], which is a commonly used form field for entering text.
class FormField<T> extends StatefulWidget { class FormField<T> extends StatefulWidget {
/// Creates a single form field.
///
/// The [builder] argument must not be null.
FormField({ FormField({
Key key, Key key,
@required this.builder, @required this.builder,
......
...@@ -72,6 +72,8 @@ class MediaQueryData { ...@@ -72,6 +72,8 @@ class MediaQueryData {
return size.width > size.height ? Orientation.landscape : Orientation.portrait; return size.width > size.height ? Orientation.landscape : Orientation.portrait;
} }
/// Creates a copy of this media query data but with the given fields replaced
/// with the new values.
MediaQueryData copyWith({ MediaQueryData copyWith({
Size size, Size size,
double devicePixelRatio, double devicePixelRatio,
......
...@@ -11,7 +11,28 @@ import 'package:flutter/rendering.dart'; ...@@ -11,7 +11,28 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
/// A visual indication that a scroll view has overscrolled.
///
/// A [GlowingOverscrollIndicator] listens for [ScrollNotification]s in order
/// to control the overscroll indication. These notifications are typically
/// generated by a [ScrolView], such as a [ListView] or a [GridView].
///
/// [GlowingOverscrollIndicator] generates [OverscrollIndicatorNotification]
/// before showing an overscroll indication. To prevent the indicator from
/// showing the indication, call [OverscrollIndicatorNotification.disallowGlow]
/// on the notification.
///
/// Created automatically by [ScrollBehavior.buildViewportChrome] on platforms
/// (e.g., Android) that commonly use this type of overscroll indication.
class GlowingOverscrollIndicator extends StatefulWidget { class GlowingOverscrollIndicator extends StatefulWidget {
/// Creates a visual indication that a scroll view has overscrolled.
///
/// In order for this widget to display an overscroll indication, the [child]
/// widget must contain a widget that generates a [ScrollNotification], such
/// as a [ListView] or a [GridView].
///
/// The [showLeading], [showTrailing], [axisDirection], and [color] arguments
/// must not be null.
GlowingOverscrollIndicator({ GlowingOverscrollIndicator({
Key key, Key key,
this.showLeading: true, this.showLeading: true,
...@@ -48,10 +69,12 @@ class GlowingOverscrollIndicator extends StatefulWidget { ...@@ -48,10 +69,12 @@ class GlowingOverscrollIndicator extends StatefulWidget {
/// viewport. /// viewport.
final bool showTrailing; final bool showTrailing;
/// The direction of positive scroll offsets in the viewport of the /// The direction of positive scroll offsets in the [Scrollable] whose
/// [Scrollable] whose overscrolls are to be visualized. /// overscrolls are to be visualized.
final AxisDirection axisDirection; final AxisDirection axisDirection;
/// The axis along which scrolling occurs in the [Scrollable] whose
/// overscrolls are to be visualized.
Axis get axis => axisDirectionToAxis(axisDirection); Axis get axis => axisDirectionToAxis(axisDirection);
/// The color of the glow. The alpha channel is ignored. /// The color of the glow. The alpha channel is ignored.
...@@ -478,11 +501,26 @@ class _GlowingOverscrollIndicatorPainter extends CustomPainter { ...@@ -478,11 +501,26 @@ class _GlowingOverscrollIndicatorPainter extends CustomPainter {
} }
} }
/// A notification that an [GlowingOverscrollIndicator] will start showing an
/// overscroll indication.
///
/// To prevent the indicator from showing the indication, call [disallowGlow] on
/// the notification.
///
/// See also:
///
/// * [GlowingOverscrollIndicator], which generates this type of notification.
class OverscrollIndicatorNotification extends Notification with ViewportNotificationMixin { class OverscrollIndicatorNotification extends Notification with ViewportNotificationMixin {
/// Creates a notification that an [GlowingOverscrollIndicator] will start
/// showing an overscroll indication.
///
/// The [leading] argument must not be null.
OverscrollIndicatorNotification({ OverscrollIndicatorNotification({
this.leading, @required this.leading,
}); });
/// Whether the indication will be shown on the leading edge of the scroll
/// view.
final bool leading; final bool leading;
bool _accepted = true; bool _accepted = true;
......
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