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