Commit ec4a6a96 authored by Adam Barth's avatar Adam Barth

Add more dartdocs to material.dart (#3279)

parent 8d02f304
...@@ -193,7 +193,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -193,7 +193,7 @@ class ListDemoState extends State<ListDemo> {
child: new Scrollbar( child: new Scrollbar(
child: new MaterialList( child: new MaterialList(
type: _itemType, type: _itemType,
scrollablePadding: new EdgeInsets.all(_dense ? 4.0 : 8.0), padding: new EdgeInsets.all(_dense ? 4.0 : 8.0),
children: listItems children: listItems
) )
) )
......
...@@ -11,7 +11,7 @@ class TwoLevelListDemo extends StatelessWidget { ...@@ -11,7 +11,7 @@ class TwoLevelListDemo extends StatelessWidget {
appBar: new AppBar(title: new Text('Expand/collapse list control')), appBar: new AppBar(title: new Text('Expand/collapse list control')),
body: new TwoLevelList( body: new TwoLevelList(
type: MaterialListType.oneLine, type: MaterialListType.oneLine,
items: <Widget>[ children: <Widget>[
new TwoLevelListItem(title: new Text('Top')), new TwoLevelListItem(title: new Text('Top')),
new TwoLevelSublist( new TwoLevelSublist(
title: new Text('Sublist'), title: new Text('Sublist'),
......
...@@ -91,10 +91,10 @@ class GalleryHomeState extends State<GalleryHome> { ...@@ -91,10 +91,10 @@ class GalleryHomeState extends State<GalleryHome> {
scrollableKey: _listKey, scrollableKey: _listKey,
appBarBehavior: AppBarBehavior.under, appBarBehavior: AppBarBehavior.under,
body: new TwoLevelList( body: new TwoLevelList(
scrollablePadding: new EdgeInsets.only(top: _kFlexibleSpaceMaxHeight + statusBarHight), padding: new EdgeInsets.only(top: _kFlexibleSpaceMaxHeight + statusBarHight),
type: MaterialListType.oneLine, type: MaterialListType.oneLine,
scrollableKey: _listKey, scrollableKey: _listKey,
items: <Widget>[ children: <Widget>[
new TwoLevelSublist( new TwoLevelSublist(
leading: new Icon(icon: Icons.star), leading: new Icon(icon: Icons.star),
title: new Text("Demos"), title: new Text("Demos"),
......
...@@ -4,13 +4,36 @@ ...@@ -4,13 +4,36 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
/// The kind of list items contained in a material design list.
///
/// See also:
///
/// * [MaterialList]
/// * [ListItem]
/// * [kListItemExtent]
/// * <https://www.google.com/design/spec/components/lists.html#lists-specs>
enum MaterialListType { enum MaterialListType {
/// A list item that contains a single line of text.
oneLine, oneLine,
/// A list item that contains a [CircleAvatar] followed by a single line of text.
oneLineWithAvatar, oneLineWithAvatar,
/// A list item that contains two lines of text.
twoLine, twoLine,
/// A list item that contains three lines of text.
threeLine threeLine
} }
/// The vertical extent of the different types of material list items.
///
/// See also:
///
/// * [MaterialListType]
/// * [ListItem]
/// * [kListItemExtent]
/// * <https://www.google.com/design/spec/components/lists.html#lists-specs>
Map<MaterialListType, double> kListItemExtent = const <MaterialListType, double>{ Map<MaterialListType, double> kListItemExtent = const <MaterialListType, double>{
MaterialListType.oneLine: 48.0, MaterialListType.oneLine: 48.0,
MaterialListType.oneLineWithAvatar: 56.0, MaterialListType.oneLineWithAvatar: 56.0,
...@@ -18,39 +41,70 @@ Map<MaterialListType, double> kListItemExtent = const <MaterialListType, double> ...@@ -18,39 +41,70 @@ Map<MaterialListType, double> kListItemExtent = const <MaterialListType, double>
MaterialListType.threeLine: 88.0, MaterialListType.threeLine: 88.0,
}; };
class MaterialList extends StatefulWidget { /// A scrollable list containing material list items.
///
/// Material list configures a [ScrollableList] with a number of default values
/// to match material design.
///
/// See also:
///
/// * [ListItem]
/// * [ScrollableList]
/// * [TwoLevelList]
/// * [ScrollableGrid]
/// * <https://www.google.com/design/spec/components/lists.html>
class MaterialList extends StatelessWidget {
/// Creates a material list.
///
/// By default, has a type of [MaterialListType.twoLine].
MaterialList({ MaterialList({
Key key, Key key,
this.initialScrollOffset, this.initialScrollOffset,
this.onScrollStart,
this.onScroll, this.onScroll,
this.onScrollEnd,
this.type: MaterialListType.twoLine, this.type: MaterialListType.twoLine,
this.children, this.children,
this.scrollablePadding: EdgeInsets.zero, this.padding: EdgeInsets.zero,
this.scrollableKey this.scrollableKey
}) : super(key: key); }) : super(key: key);
/// The scroll offset this widget should use when first created.
final double initialScrollOffset; final double initialScrollOffset;
/// Called whenever this widget starts to scroll.
final ScrollListener onScrollStart;
/// Called whenever this widget's scroll offset changes.
final ScrollListener onScroll; final ScrollListener onScroll;
/// Called whenever this widget stops scrolling.
final ScrollListener onScrollEnd;
/// The kind of [ListItem] contained in this list.
final MaterialListType type; final MaterialListType type;
/// The widgets to display in this list.
final Iterable<Widget> children; final Iterable<Widget> children;
final EdgeInsets scrollablePadding;
final Key scrollableKey;
@override /// The amount of space by which to inset the children inside the viewport.
_MaterialListState createState() => new _MaterialListState(); final EdgeInsets padding;
}
/// The key to use for the underlying scrollable widget.
final Key scrollableKey;
class _MaterialListState extends State<MaterialList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new ScrollableList( return new ScrollableList(
key: config.scrollableKey, key: scrollableKey,
initialScrollOffset: config.initialScrollOffset, initialScrollOffset: initialScrollOffset,
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
onScroll: config.onScroll, onScrollStart: onScrollStart,
itemExtent: kListItemExtent[config.type], onScroll: onScroll,
padding: const EdgeInsets.symmetric(vertical: 8.0) + config.scrollablePadding, onScrollEnd: onScrollEnd,
children: config.children itemExtent: kListItemExtent[type],
padding: const EdgeInsets.symmetric(vertical: 8.0) + padding,
children: children
); );
} }
} }
...@@ -118,7 +118,7 @@ class ListItem extends StatelessWidget { ...@@ -118,7 +118,7 @@ class ListItem extends StatelessWidget {
yield item; yield item;
} }
TextStyle primaryTextStyle(BuildContext context) { TextStyle _primaryTextStyle(BuildContext context) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TextStyle style = theme.textTheme.subhead; final TextStyle style = theme.textTheme.subhead;
if (!enabled) { if (!enabled) {
...@@ -128,7 +128,7 @@ class ListItem extends StatelessWidget { ...@@ -128,7 +128,7 @@ class ListItem extends StatelessWidget {
return dense ? style.copyWith(fontSize: 13.0) : style; return dense ? style.copyWith(fontSize: 13.0) : style;
} }
TextStyle secondaryTextStyle(BuildContext context) { TextStyle _secondaryTextStyle(BuildContext context) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final Color color = theme.textTheme.caption.color; final Color color = theme.textTheme.caption.color;
final TextStyle style = theme.textTheme.body1; final TextStyle style = theme.textTheme.body1;
...@@ -167,7 +167,7 @@ class ListItem extends StatelessWidget { ...@@ -167,7 +167,7 @@ class ListItem extends StatelessWidget {
} }
final Widget primaryLine = new DefaultTextStyle( final Widget primaryLine = new DefaultTextStyle(
style: primaryTextStyle(context), style: _primaryTextStyle(context),
child: title ?? new Container() child: title ?? new Container()
); );
Widget center = primaryLine; Widget center = primaryLine;
...@@ -178,7 +178,7 @@ class ListItem extends StatelessWidget { ...@@ -178,7 +178,7 @@ class ListItem extends StatelessWidget {
children: <Widget>[ children: <Widget>[
primaryLine, primaryLine,
new DefaultTextStyle( new DefaultTextStyle(
style: secondaryTextStyle(context), style: _secondaryTextStyle(context),
child: subtitle child: subtitle
) )
] ]
......
...@@ -12,6 +12,11 @@ import 'constants.dart'; ...@@ -12,6 +12,11 @@ import 'constants.dart';
import 'shadows.dart'; import 'shadows.dart';
import 'theme.dart'; import 'theme.dart';
/// The various kinds of material in material design.
///
/// See also:
/// * [Material]
/// * [kMaterialEdges]
enum MaterialType { enum MaterialType {
/// Infinite extent using default theme canvas color. /// Infinite extent using default theme canvas color.
canvas, canvas,
...@@ -29,6 +34,12 @@ enum MaterialType { ...@@ -29,6 +34,12 @@ enum MaterialType {
transparency transparency
} }
/// The border radii used by the various kinds of material in material design.
///
/// See also:
///
/// * [MaterialType]
/// * [Material]
const Map<MaterialType, double> kMaterialEdges = const <MaterialType, double>{ const Map<MaterialType, double> kMaterialEdges = const <MaterialType, double>{
MaterialType.canvas: null, MaterialType.canvas: null,
MaterialType.card: 2.0, MaterialType.card: 2.0,
...@@ -37,23 +48,50 @@ const Map<MaterialType, double> kMaterialEdges = const <MaterialType, double>{ ...@@ -37,23 +48,50 @@ const Map<MaterialType, double> kMaterialEdges = const <MaterialType, double>{
MaterialType.transparency: null, MaterialType.transparency: null,
}; };
/// A visual reaction on a piece of [Material] to user input.
///
/// Typically created by [MaterialInkController.splashAt].
abstract class InkSplash { abstract class InkSplash {
/// The user input is confirmed.
///
/// Causes the reaction to propagate faster across the material.
void confirm(); void confirm();
/// The user input was cancelled.
///
/// Causes the reaction to gradually disappear.
void cancel(); void cancel();
/// Free up the resources associated with this reaction.
void dispose(); void dispose();
} }
/// A visual emphasis on a part of a [Material] receiving user interaction.
///
/// Typically created by [MaterialInkController.highlightAt].
abstract class InkHighlight { abstract class InkHighlight {
/// Start visually emphasizing this part of the material.
void activate(); void activate();
/// Stop visually emphasizing this part of the material.
void deactivate(); void deactivate();
/// Free up the resources associated with this highlight.
void dispose(); void dispose();
/// Whether this part of the material is being visually emphasized.
bool get active; bool get active;
/// The color use to visually represent the emphasis.
Color get color; Color get color;
void set color(Color value); void set color(Color value);
} }
/// An interface for creating [InkSplash]s and [InkHighlight]s on a material.
///
/// Typically obtained via [Material.of].
abstract class MaterialInkController { abstract class MaterialInkController {
/// The color of the material /// The color of the material.
Color get color; Color get color;
/// Begin a splash, centered at position relative to referenceBox. /// Begin a splash, centered at position relative to referenceBox.
...@@ -69,11 +107,31 @@ abstract class MaterialInkController { ...@@ -69,11 +107,31 @@ abstract class MaterialInkController {
void addInkFeature(InkFeature feature); void addInkFeature(InkFeature feature);
} }
/// Describes a sheet of Material. If the layout changes (e.g. because there's a /// A piece of material.
/// list on the paper, and it's been scrolled), a LayoutChangedNotification must ///
/// be dispatched at the relevant subtree. (This in particular means that /// Material is the central metaphor in material design. Each piece of material
/// Transitions should not be placed inside Material.) /// exists at a given elevation, which influences how that piece of material
/// visually relates to other pieces of material and how that material casts
/// shadows on other pieces of material.
///
/// Most user interface elements are either conceptually printed on a piece of
/// material or themselves made of material. Material reacts to user input using
/// [InkSplash] and [InkHighlight] effects. To trigger a reaction on the
/// material, use a [MaterialInkController] obtained via [Material.of].
///
/// If the layout changes (e.g. because there's a list on the paper, and it's
/// been scrolled), a LayoutChangedNotification must be dispatched at the
/// relevant subtree. (This in particular means that Transitions should not be
/// placed inside Material.) Otherwise, in-progress ink features (e.g., ink
/// splashes and ink highlights) won't move to account for the new layout.
///
/// See also:
///
/// * <https://www.google.com/design/spec/material-design/introduction.html>
class Material extends StatefulWidget { class Material extends StatefulWidget {
/// Creates a piece of material.
///
/// Both the type and the elevation arguments are required.
Material({ Material({
Key key, Key key,
this.child, this.child,
...@@ -89,18 +147,24 @@ class Material extends StatefulWidget { ...@@ -89,18 +147,24 @@ class Material extends StatefulWidget {
/// The widget below this widget in the tree. /// The widget below this widget in the tree.
final Widget child; final Widget child;
/// The kind of material (e.g., card or canvas).
final MaterialType type; final MaterialType type;
/// The z-coordinate at which to place this material. /// The z-coordinate at which to place this material.
final int elevation; final int elevation;
/// The color of the material.
///
/// Must be opaque. To create a transparent piece of material, use
/// [MaterialType.transparency].
final Color color; final Color color;
/// The typographical style to use for text within this material.
final TextStyle textStyle; final TextStyle textStyle;
/// The ink controller from the closest instance of this class that encloses the given context. /// The ink controller from the closest instance of this class that encloses the given context.
static MaterialInkController of(BuildContext context) { static MaterialInkController of(BuildContext context) {
final RenderInkFeatures result = context.ancestorRenderObjectOfType(const TypeMatcher<RenderInkFeatures>()); final _RenderInkFeatures result = context.ancestorRenderObjectOfType(const TypeMatcher<_RenderInkFeatures>());
return result; return result;
} }
...@@ -147,7 +211,7 @@ class _MaterialState extends State<Material> { ...@@ -147,7 +211,7 @@ class _MaterialState extends State<Material> {
onNotification: (LayoutChangedNotification notification) { onNotification: (LayoutChangedNotification notification) {
_inkFeatureRenderer.currentContext.findRenderObject().markNeedsPaint(); _inkFeatureRenderer.currentContext.findRenderObject().markNeedsPaint();
}, },
child: new InkFeatures( child: new _InkFeatures(
key: _inkFeatureRenderer, key: _inkFeatureRenderer,
color: backgroundColor, color: backgroundColor,
child: contents child: contents
...@@ -192,8 +256,8 @@ const double _kDefaultSplashRadius = 35.0; // logical pixels ...@@ -192,8 +256,8 @@ const double _kDefaultSplashRadius = 35.0; // logical pixels
const double _kSplashConfirmedVelocity = 1.0; // logical pixels per millisecond const double _kSplashConfirmedVelocity = 1.0; // logical pixels per millisecond
const double _kSplashInitialSize = 0.0; // logical pixels const double _kSplashInitialSize = 0.0; // logical pixels
class RenderInkFeatures extends RenderProxyBox implements MaterialInkController { class _RenderInkFeatures extends RenderProxyBox implements MaterialInkController {
RenderInkFeatures({ RenderBox child, this.color }) : super(child); _RenderInkFeatures({ RenderBox child, this.color }) : super(child);
// This is here to satisfy the MaterialInkController contract. // This is here to satisfy the MaterialInkController contract.
// The actual painting of this color is done by a Container in the // The actual painting of this color is done by a Container in the
...@@ -289,33 +353,44 @@ class RenderInkFeatures extends RenderProxyBox implements MaterialInkController ...@@ -289,33 +353,44 @@ class RenderInkFeatures extends RenderProxyBox implements MaterialInkController
} }
} }
class InkFeatures extends SingleChildRenderObjectWidget { class _InkFeatures extends SingleChildRenderObjectWidget {
InkFeatures({ Key key, this.color, Widget child }) : super(key: key, child: child); _InkFeatures({ Key key, this.color, Widget child }) : super(key: key, child: child);
final Color color; final Color color;
@override @override
RenderInkFeatures createRenderObject(BuildContext context) => new RenderInkFeatures(color: color); _RenderInkFeatures createRenderObject(BuildContext context) => new _RenderInkFeatures(color: color);
@override @override
void updateRenderObject(BuildContext context, RenderInkFeatures renderObject) { void updateRenderObject(BuildContext context, _RenderInkFeatures renderObject) {
renderObject.color = color; renderObject.color = color;
} }
} }
/// A visual reaction on a piece of [Material].
///
/// Typically used with [MaterialInkController].
abstract class InkFeature { abstract class InkFeature {
/// To add an ink feature to a piece of Material, obtain the
/// [MaterialInkController] via [Material.of] and call
/// [MaterialInkController.addInkFeature].
InkFeature({ InkFeature({
this.renderer, this.renderer,
this.referenceBox, this.referenceBox,
this.onRemoved this.onRemoved
}); });
final RenderInkFeatures renderer; final _RenderInkFeatures renderer;
/// The render box whose visual position defines the frame of reference for this ink feature.
final RenderBox referenceBox; final RenderBox referenceBox;
/// Called when the ink feature is no longer visible on the material.
final VoidCallback onRemoved; final VoidCallback onRemoved;
bool _debugDisposed = false; bool _debugDisposed = false;
/// Free up the resources associated with this ink feature.
void dispose() { void dispose() {
assert(!_debugDisposed); assert(!_debugDisposed);
assert(() { _debugDisposed = true; return true; }); assert(() { _debugDisposed = true; return true; });
...@@ -343,6 +418,10 @@ abstract class InkFeature { ...@@ -343,6 +418,10 @@ abstract class InkFeature {
paintFeature(canvas, transform); paintFeature(canvas, transform);
} }
/// Override this method to paint the ink feature.
///
/// The transform argument gives the coordinate conversion from the coordinate
/// system of the canvas to the coodinate system of the [referenceBox].
void paintFeature(Canvas canvas, Matrix4 transform); void paintFeature(Canvas canvas, Matrix4 transform);
@override @override
...@@ -351,7 +430,7 @@ abstract class InkFeature { ...@@ -351,7 +430,7 @@ abstract class InkFeature {
class _InkSplash extends InkFeature implements InkSplash { class _InkSplash extends InkFeature implements InkSplash {
_InkSplash({ _InkSplash({
RenderInkFeatures renderer, _RenderInkFeatures renderer,
RenderBox referenceBox, RenderBox referenceBox,
this.position, this.position,
this.color, this.color,
...@@ -445,7 +524,7 @@ class _InkSplash extends InkFeature implements InkSplash { ...@@ -445,7 +524,7 @@ class _InkSplash extends InkFeature implements InkSplash {
class _InkHighlight extends InkFeature implements InkHighlight { class _InkHighlight extends InkFeature implements InkHighlight {
_InkHighlight({ _InkHighlight({
RenderInkFeatures renderer, _RenderInkFeatures renderer,
RenderBox referenceBox, RenderBox referenceBox,
Color color, Color color,
this.shape, this.shape,
......
...@@ -161,21 +161,30 @@ class TwoLevelList extends StatelessWidget { ...@@ -161,21 +161,30 @@ class TwoLevelList extends StatelessWidget {
TwoLevelList({ TwoLevelList({
Key key, Key key,
this.scrollableKey, this.scrollableKey,
this.items, this.children,
this.type: MaterialListType.twoLine, this.type: MaterialListType.twoLine,
this.scrollablePadding this.padding
}) : super(key: key); }) : super(key: key);
final List<Widget> items; /// The widgets to display in this list.
///
/// Typically [TwoLevelListItem] or [TwoLevelSublist] widgets.
final List<Widget> children;
/// The kind of [ListItem] contained in this list.
final MaterialListType type; final MaterialListType type;
/// The key to use for the underlying scrollable widget.
final Key scrollableKey; final Key scrollableKey;
final EdgeInsets scrollablePadding;
/// The amount of space by which to inset the children inside the viewport.
final EdgeInsets padding;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Block( return new Block(
padding: scrollablePadding, padding: padding,
children: KeyedSubtree.ensureUniqueKeysForList(items), children: KeyedSubtree.ensureUniqueKeysForList(children),
scrollableKey: scrollableKey scrollableKey: scrollableKey
); );
} }
......
...@@ -135,7 +135,9 @@ class LazyBlock extends Scrollable { ...@@ -135,7 +135,9 @@ class LazyBlock extends Scrollable {
Key key, Key key,
double initialScrollOffset, double initialScrollOffset,
Axis scrollDirection: Axis.vertical, Axis scrollDirection: Axis.vertical,
ScrollListener onScrollStart,
ScrollListener onScroll, ScrollListener onScroll,
ScrollListener onScrollEnd,
SnapOffsetCallback snapOffsetCallback, SnapOffsetCallback snapOffsetCallback,
this.delegate, this.delegate,
this.padding this.padding
...@@ -143,7 +145,9 @@ class LazyBlock extends Scrollable { ...@@ -143,7 +145,9 @@ class LazyBlock extends Scrollable {
key: key, key: key,
initialScrollOffset: initialScrollOffset, initialScrollOffset: initialScrollOffset,
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
onScrollStart: onScrollStart,
onScroll: onScroll, onScroll: onScroll,
onScrollEnd: onScrollEnd,
snapOffsetCallback: snapOffsetCallback snapOffsetCallback: snapOffsetCallback
); );
......
...@@ -733,7 +733,9 @@ class Block extends StatelessWidget { ...@@ -733,7 +733,9 @@ class Block extends StatelessWidget {
this.initialScrollOffset, this.initialScrollOffset,
this.scrollDirection: Axis.vertical, this.scrollDirection: Axis.vertical,
this.scrollAnchor: ViewportAnchor.start, this.scrollAnchor: ViewportAnchor.start,
this.onScrollStart,
this.onScroll, this.onScroll,
this.onScrollEnd,
this.scrollableKey this.scrollableKey
}) : super(key: key) { }) : super(key: key) {
assert(children != null); assert(children != null);
...@@ -745,10 +747,22 @@ class Block extends StatelessWidget { ...@@ -745,10 +747,22 @@ class Block extends StatelessWidget {
/// The amount of space by which to inset the children inside the viewport. /// The amount of space by which to inset the children inside the viewport.
final EdgeInsets padding; final EdgeInsets padding;
/// The scroll offset this widget should use when first created.
final double initialScrollOffset; final double initialScrollOffset;
final Axis scrollDirection; final Axis scrollDirection;
final ViewportAnchor scrollAnchor; final ViewportAnchor scrollAnchor;
/// Called whenever this widget starts to scroll.
final ScrollListener onScrollStart;
/// Called whenever this widget's scroll offset changes.
final ScrollListener onScroll; final ScrollListener onScroll;
/// Called whenever this widget stops scrolling.
final ScrollListener onScrollEnd;
/// The key to use for the underlying scrollable widget.
final Key scrollableKey; final Key scrollableKey;
@override @override
...@@ -761,7 +775,9 @@ class Block extends StatelessWidget { ...@@ -761,7 +775,9 @@ class Block extends StatelessWidget {
initialScrollOffset: initialScrollOffset, initialScrollOffset: initialScrollOffset,
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
scrollAnchor: scrollAnchor, scrollAnchor: scrollAnchor,
onScrollStart: onScrollStart,
onScroll: onScroll, onScroll: onScroll,
onScrollEnd: onScrollEnd,
child: contents child: contents
); );
} }
......
...@@ -19,7 +19,9 @@ class ScrollableGrid extends Scrollable { ...@@ -19,7 +19,9 @@ class ScrollableGrid extends Scrollable {
ScrollableGrid({ ScrollableGrid({
Key key, Key key,
double initialScrollOffset, double initialScrollOffset,
ScrollListener onScrollStart,
ScrollListener onScroll, ScrollListener onScroll,
ScrollListener onScrollEnd,
SnapOffsetCallback snapOffsetCallback, SnapOffsetCallback snapOffsetCallback,
this.delegate, this.delegate,
this.children this.children
...@@ -30,7 +32,9 @@ class ScrollableGrid extends Scrollable { ...@@ -30,7 +32,9 @@ class ScrollableGrid extends Scrollable {
// grids. For horizontally scrolling grids, we'll probably need to use a // grids. For horizontally scrolling grids, we'll probably need to use a
// delegate that places children in column-major order. // delegate that places children in column-major order.
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
onScrollStart: onScrollStart,
onScroll: onScroll, onScroll: onScroll,
onScrollEnd: onScrollEnd,
snapOffsetCallback: snapOffsetCallback snapOffsetCallback: snapOffsetCallback
); );
......
...@@ -51,7 +51,9 @@ class ScrollableList extends Scrollable { ...@@ -51,7 +51,9 @@ class ScrollableList extends Scrollable {
double initialScrollOffset, double initialScrollOffset,
Axis scrollDirection: Axis.vertical, Axis scrollDirection: Axis.vertical,
ViewportAnchor scrollAnchor: ViewportAnchor.start, ViewportAnchor scrollAnchor: ViewportAnchor.start,
ScrollListener onScrollStart,
ScrollListener onScroll, ScrollListener onScroll,
ScrollListener onScrollEnd,
SnapOffsetCallback snapOffsetCallback, SnapOffsetCallback snapOffsetCallback,
this.itemExtent, this.itemExtent,
this.itemsWrap: false, this.itemsWrap: false,
...@@ -62,7 +64,9 @@ class ScrollableList extends Scrollable { ...@@ -62,7 +64,9 @@ class ScrollableList extends Scrollable {
initialScrollOffset: initialScrollOffset, initialScrollOffset: initialScrollOffset,
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
scrollAnchor: scrollAnchor, scrollAnchor: scrollAnchor,
onScrollStart: onScrollStart,
onScroll: onScroll, onScroll: onScroll,
onScrollEnd: onScrollEnd,
snapOffsetCallback: snapOffsetCallback snapOffsetCallback: snapOffsetCallback
) { ) {
assert(itemExtent != null); assert(itemExtent != null);
......
...@@ -18,7 +18,7 @@ void main() { ...@@ -18,7 +18,7 @@ void main() {
return new Material( return new Material(
child: new Viewport( child: new Viewport(
child: new TwoLevelList( child: new TwoLevelList(
items: <Widget>[ children: <Widget>[
new TwoLevelListItem(title: new Text('Top'), key: topKey), new TwoLevelListItem(title: new Text('Top'), key: topKey),
new TwoLevelSublist( new TwoLevelSublist(
key: sublistKey, key: sublistKey,
......
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