Add more docs about scrolling (#9711)
This commit is contained in:
parent
ea96773fd1
commit
49d32d35ea
@ -62,7 +62,7 @@ bool debugPaintBaselinesEnabled = false;
|
||||
/// The color to use when painting alphabetic baselines.
|
||||
Color debugPaintAlphabeticBaselineColor = _kDebugPaintAlphabeticBaselineColor;
|
||||
|
||||
/// The color ot use when painting ideographic baselines.
|
||||
/// The color to use when painting ideographic baselines.
|
||||
Color debugPaintIdeographicBaselineColor = _kDebugPaintIdeographicBaselineColor;
|
||||
|
||||
/// Causes each Layer to paint a box around its bounds.
|
||||
|
@ -201,6 +201,15 @@ class ScrollController extends ChangeNotifier {
|
||||
return '$runtimeType#$hashCode(${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 [ScrollController] 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
|
||||
void debugFillDescription(List<String> description) {
|
||||
if (debugLabel != null)
|
||||
|
@ -7,7 +7,7 @@ import 'dart:math' as math;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
/// A description of a [Scrollable]'s contents, useful for modelling the state
|
||||
/// A description of a [Scrollable]'s contents, useful for modeling the state
|
||||
/// of its viewport.
|
||||
///
|
||||
/// This class defines a current position, [pixels], and a range of values
|
||||
|
@ -39,13 +39,41 @@ abstract class ViewportNotificationMixin extends Notification {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [Notification] related to scrolling.
|
||||
///
|
||||
/// [Scrollable] widgets notify their ancestors about scrolling-related changes.
|
||||
/// The notifications have the following lifecycle:
|
||||
///
|
||||
/// * A [ScrollStartNotification], which indicates that the widget has started
|
||||
/// scrolling.
|
||||
/// * Zero or more [ScrollUpdateNotification]s, which indicate that the widget
|
||||
/// has changed its scroll position, mixed with zero or more
|
||||
/// [OverscrollNotification]s, which indicate that the widget has not changed
|
||||
/// its scroll position because the change would have caused its scroll
|
||||
/// position to go outside its scroll bounds.
|
||||
/// * Interspersed with the [ScrollUpdateNotification]s and
|
||||
/// [OverscrollNotification]s are zero or more [UserScrollNotification]s,
|
||||
/// which indicate that the user has changed the direciton in which they are
|
||||
/// scrolling.
|
||||
/// * A [ScrollEndNotification], which indicates that the widget has stopped
|
||||
/// scrolling.
|
||||
/// * A [UserScrollNotification], with a [UserScrollNotification.direciton] of
|
||||
/// [ScrollDirection.idle].
|
||||
///
|
||||
/// Notifications bubble up through the tree, which means a given
|
||||
/// [NotificationListener] will receive notifications for all descendant
|
||||
/// [Scrollable] widgets. To focus on notifications from the nearest
|
||||
/// [Scrollable] descendant, check that the [depth] property of the notification
|
||||
/// is zero.
|
||||
abstract class ScrollNotification extends LayoutChangedNotification with ViewportNotificationMixin {
|
||||
/// Creates a notification about scrolling.
|
||||
/// Initializes fields for subclasses.
|
||||
ScrollNotification({
|
||||
@required this.metrics,
|
||||
@required this.context,
|
||||
});
|
||||
|
||||
// A description of a [Scrollable]'s contents, useful for modeling the state
|
||||
/// of its viewport.
|
||||
final ScrollMetrics metrics;
|
||||
|
||||
/// The build context of the widget that fired this notification.
|
||||
@ -61,13 +89,24 @@ abstract class ScrollNotification extends LayoutChangedNotification with Viewpor
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that a [Scrollable] widget has started scrolling.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ScrollEndNotification], which indicates that scrolling has stopped.
|
||||
/// * [ScrollNotification], which describes the notification lifecycle.
|
||||
class ScrollStartNotification extends ScrollNotification {
|
||||
/// Creates a notification that a [Scrollable] widget has started scrolling.
|
||||
ScrollStartNotification({
|
||||
@required ScrollMetrics metrics,
|
||||
@required BuildContext context,
|
||||
this.dragDetails,
|
||||
}) : super(metrics: metrics, context: context);
|
||||
|
||||
/// If the [Scrollable] started scrolling because of a drag, the details about
|
||||
/// that drag start.
|
||||
///
|
||||
/// Otherwise, null.
|
||||
final DragStartDetails dragDetails;
|
||||
|
||||
@override
|
||||
@ -78,7 +117,17 @@ class ScrollStartNotification extends ScrollNotification {
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that a [Scrollable] widget has changed its scroll position.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [OverscrollNotification], which indicates that a [Scrollable] widget
|
||||
/// has not changed its scroll position because the change would have caused
|
||||
/// its scroll position to go outside its scroll bounds.
|
||||
/// * [ScrollNotification], which describes the notification lifecycle.
|
||||
class ScrollUpdateNotification extends ScrollNotification {
|
||||
/// Creates a notification that a [Scrollable] widget has changed its scroll
|
||||
/// position.
|
||||
ScrollUpdateNotification({
|
||||
@required ScrollMetrics metrics,
|
||||
@required BuildContext context,
|
||||
@ -86,6 +135,10 @@ class ScrollUpdateNotification extends ScrollNotification {
|
||||
this.scrollDelta,
|
||||
}) : super(metrics: metrics, context: context);
|
||||
|
||||
/// If the [Scrollable] changed its scroll position because of a drag, the
|
||||
/// details about that drag update.
|
||||
///
|
||||
/// Otherwise, null.
|
||||
final DragUpdateDetails dragDetails;
|
||||
|
||||
/// The distance by which the [Scrollable] was scrolled, in logical pixels.
|
||||
@ -100,7 +153,18 @@ class ScrollUpdateNotification extends ScrollNotification {
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that a [Scrollable] widget has not changed its scroll position
|
||||
/// because the change would have caused its scroll position to go outside of
|
||||
/// its scroll bounds.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ScrollUpdateNotification], which indicates that a [Scrollable] widget
|
||||
/// has changed its scroll position.
|
||||
/// * [ScrollNotification], which describes the notification lifecycle.
|
||||
class OverscrollNotification extends ScrollNotification {
|
||||
/// Creates a notification that a [Scrollable] widget has changed its scroll
|
||||
/// position outside of its scroll bounds.
|
||||
OverscrollNotification({
|
||||
@required ScrollMetrics metrics,
|
||||
@required BuildContext context,
|
||||
@ -114,6 +178,10 @@ class OverscrollNotification extends ScrollNotification {
|
||||
assert(velocity != null);
|
||||
}
|
||||
|
||||
/// If the [Scrollable] overscrolled because of a drag, the details about that
|
||||
/// drag update.
|
||||
///
|
||||
/// Otherwise, null.
|
||||
final DragUpdateDetails dragDetails;
|
||||
|
||||
/// The number of logical pixels that the [Scrollable] avoided scrolling.
|
||||
@ -140,13 +208,31 @@ class OverscrollNotification extends ScrollNotification {
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that a [Scrollable] widget has stopped scrolling.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ScrollStartNotification], which indicates that scrolling has started.
|
||||
/// * [ScrollNotification], which describes the notification lifecycle.
|
||||
class ScrollEndNotification extends ScrollNotification {
|
||||
/// Creates a notification that a [Scrollable] widget has stopped scrolling.
|
||||
ScrollEndNotification({
|
||||
@required ScrollMetrics metrics,
|
||||
@required BuildContext context,
|
||||
this.dragDetails,
|
||||
}) : super(metrics: metrics, context: context);
|
||||
|
||||
/// If the [Scrollable] stopped scrolling because of a drag, the details about
|
||||
/// that drag end.
|
||||
///
|
||||
/// Otherwise, null.
|
||||
///
|
||||
/// If a drag ends with some residual velocity, a typical [ScrollPhysics] will
|
||||
/// start a ballistic scroll, which delays the [ScrollEndNotification] until
|
||||
/// the ballistic simulation completes, at which time [dragDetails] will
|
||||
/// be null. If the residtual velocity is too small to trigger ballistic
|
||||
/// scrolling, then the [ScrollEndNotification] will be dispatched immediately
|
||||
/// and [dragDetails] will be non-null.
|
||||
final DragEndDetails dragDetails;
|
||||
|
||||
@override
|
||||
@ -157,13 +243,22 @@ class ScrollEndNotification extends ScrollNotification {
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that the user has changed the direction in which they are
|
||||
/// scrolling.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ScrollNotification], which describes the notification lifecycle.
|
||||
class UserScrollNotification extends ScrollNotification {
|
||||
/// Creates a notification that the user has changed the direction in which
|
||||
/// they are scrolling.
|
||||
UserScrollNotification({
|
||||
@required ScrollMetrics metrics,
|
||||
@required BuildContext context,
|
||||
this.direction,
|
||||
}) : super(metrics: metrics, context: context);
|
||||
|
||||
/// The direction in which the user is scrolling.
|
||||
final ScrollDirection direction;
|
||||
|
||||
@override
|
||||
|
@ -15,12 +15,34 @@ import 'scroll_simulation.dart';
|
||||
|
||||
export 'package:flutter/physics.dart' show Tolerance;
|
||||
|
||||
/// Determines the physics of a [Scrollable] widget.
|
||||
///
|
||||
/// For example, determines how the [Scrollable] will behave when the user
|
||||
/// reaches the maximum scroll extent or when the user stops scrolling.
|
||||
///
|
||||
/// When starting a physics [Simulation], the current scroll position and
|
||||
/// velocity are used as the initial conditions for the particle in the
|
||||
/// simulation. The movement of the particle in the simulation is then used to
|
||||
/// determine the scroll position for the widget.
|
||||
@immutable
|
||||
class ScrollPhysics {
|
||||
/// Creates an object with the default scroll physics.
|
||||
const ScrollPhysics({ this.parent });
|
||||
|
||||
/// If non-null, determines the default behavior for each method.
|
||||
///
|
||||
/// If a subclass of [ScrollPhysics] does not override a method, that subclass
|
||||
/// will inherit an implementation from this base class that defers to
|
||||
/// [parent]. This mechanism lets you assemble novel combinations of
|
||||
/// [ScrollPhysics] subclasses at runtime.
|
||||
final ScrollPhysics parent;
|
||||
|
||||
/// Return a [ScrollPhysics] with the same [runtimeType] where the [parent]
|
||||
/// has been replaced with the given [parent].
|
||||
///
|
||||
/// The returned object will combine some of the behaviors from this
|
||||
/// [ScrollPhysics] instance and some of the behaviors from the given
|
||||
/// [ScrollPhysics] instance.
|
||||
ScrollPhysics applyTo(ScrollPhysics parent) => new ScrollPhysics(parent: parent);
|
||||
|
||||
/// Used by [DragScrollActivity] and other user-driven activities to
|
||||
@ -111,6 +133,7 @@ class ScrollPhysics {
|
||||
ratio: 1.1,
|
||||
);
|
||||
|
||||
/// The spring to use for ballistic simulations.
|
||||
SpringDescription get spring => parent?.spring ?? _kDefaultSpring;
|
||||
|
||||
/// The default accuracy to which scrolling is computed.
|
||||
@ -121,6 +144,7 @@ class ScrollPhysics {
|
||||
distance: 1.0 / ui.window.devicePixelRatio // logical pixels
|
||||
);
|
||||
|
||||
/// The tolerance to use for ballistic simulations.
|
||||
Tolerance get tolerance => parent?.tolerance ?? _kDefaultTolerance;
|
||||
|
||||
/// The minimum distance an input pointer drag must have moved to
|
||||
|
@ -120,8 +120,16 @@ class ClampingScrollSimulation extends Simulation {
|
||||
_distance = (velocity * _duration / _kInitialVelocityPenetration).abs();
|
||||
}
|
||||
|
||||
/// The position of the particle at the beginning of the simulation.
|
||||
final double position;
|
||||
|
||||
/// The velocity at which the particle is traveling at the beginning of the
|
||||
/// simulation.
|
||||
final double velocity;
|
||||
|
||||
/// The amount of friction the particle experiences as it travels.
|
||||
///
|
||||
/// The more friction the particle experiences, the sooner it stops.
|
||||
final double friction;
|
||||
|
||||
double _duration;
|
||||
|
@ -24,9 +24,53 @@ import 'viewport.dart';
|
||||
|
||||
export 'package:flutter/physics.dart' show Tolerance;
|
||||
|
||||
/// Signature used by [Scrollable] to build the viewport through which the
|
||||
/// scrollable content is displayed.
|
||||
typedef Widget ViewportBuilder(BuildContext context, ViewportOffset position);
|
||||
|
||||
/// A widget that scrolls.
|
||||
///
|
||||
/// [Scrollable] implements the interaction model for a scrollable widget,
|
||||
/// including gesture recognition, but does not have an opinion about how the
|
||||
/// viewport, which actually displays the children, is constructed.
|
||||
///
|
||||
/// It's rare to construct a [Scrollable] directly. Instead, consider [ListView]
|
||||
/// or [GridView], which combine scrolling, viewporting, and a layout model. To
|
||||
/// combine layout models (or to use a custom layout mode), consider using
|
||||
/// [CustomScrollView].
|
||||
///
|
||||
/// The static [Scrollable.of] and [Scrollable.ensureVisible] functions are
|
||||
/// often used to interact with the [Scrollable] widget inside a [ListView] or
|
||||
/// a [GridView].
|
||||
///
|
||||
/// To further customize scrolling behavior with a [Scrollable]:
|
||||
///
|
||||
/// 1. You can provide a [viewportBuilder] to customize the child model. For
|
||||
/// example, [SingleChildScrollView] uses a viewport that displays a single
|
||||
/// box child whereas [CustomScrollView] uses a [Viewport] or a
|
||||
/// [ShrinkWrappingViewport], both of which display a list of slivers.
|
||||
///
|
||||
/// 2. You can provide a custom [ScrollController] that creates a custom
|
||||
/// [ScrollPosition] subclass. For example, [PageView] uses a
|
||||
/// [PageController], which creates a page-oriented scroll position subclass
|
||||
/// that keeps the same page visible when the [Scrollable] resizes.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ListView], which is a commonly used [ScrollView] that displays a
|
||||
/// scrolling, linear list of child widgets.
|
||||
/// * [PageView], which is a scrolling list of child widgets that are each the
|
||||
/// size of the viewport.
|
||||
/// * [GridView], which is a [ScrollView] that displays a scrolling, 2D array
|
||||
/// of child widgets.
|
||||
/// * [CustomScrollView], which is a [ScrollView] that creates custom scroll
|
||||
/// effects using slivers.
|
||||
/// * [SingleChildScrollView], which is a scrollable widget that has a single
|
||||
/// child.
|
||||
class Scrollable extends StatefulWidget {
|
||||
/// Creates a widget that scrolls.
|
||||
///
|
||||
/// The [axisDirection] and [viewportBuilder] arguments must not be null.
|
||||
const Scrollable({
|
||||
Key key,
|
||||
this.axisDirection: AxisDirection.down,
|
||||
@ -37,14 +81,50 @@ class Scrollable extends StatefulWidget {
|
||||
assert(viewportBuilder != null),
|
||||
super (key: key);
|
||||
|
||||
/// The direction in which this widget scrolls.
|
||||
///
|
||||
/// For example, if the [axisDirection] is [AxisDirection.down], increasing
|
||||
/// the scroll position will cause content below the bottom of the viewport to
|
||||
/// become visible through the viewport. Similarly, if [axisDirection] is
|
||||
/// [AxisDirection.right], increasing the scroll position will cause content
|
||||
/// beyond the right edge of the viewport to become visible through the
|
||||
/// viewport.
|
||||
///
|
||||
/// Defaults to [AxisDirection.down].
|
||||
final AxisDirection axisDirection;
|
||||
|
||||
/// An object that can be used to control the position to which this widget is
|
||||
/// scrolled.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ensureVisible], which animates the scroll position to reveal a given
|
||||
/// [BuildContext].
|
||||
final ScrollController controller;
|
||||
|
||||
/// How the widgets should respond to user input.
|
||||
///
|
||||
/// For example, determines how the widget continues to animate after the
|
||||
/// user stops dragging the scroll view.
|
||||
///
|
||||
/// Defaults to matching platform conventions.
|
||||
final ScrollPhysics physics;
|
||||
|
||||
/// Builds the viewport through which the scrollable content is displayed.
|
||||
///
|
||||
/// A typical viewport uses the given [ViewportOffset] to determine which part
|
||||
/// of its content is actually visible through the viewport.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Viewport], which is a viewport that displays a list of slivers.
|
||||
/// * [ShrinkWrappingViewport], which is a viewport that displays a list of
|
||||
/// slivers and sizes itself based on the size of the slivers.
|
||||
final ViewportBuilder viewportBuilder;
|
||||
|
||||
/// The axis along which the scroll view scrolls.
|
||||
///
|
||||
/// Determined by the [axisDirection].
|
||||
Axis get axis => axisDirectionToAxis(axisDirection);
|
||||
|
||||
@override
|
||||
|
Loading…
x
Reference in New Issue
Block a user