diff --git a/examples/material_gallery/lib/demo/grid_list_demo.dart b/examples/material_gallery/lib/demo/grid_list_demo.dart index 84737642bc..e7eb481f2f 100644 --- a/examples/material_gallery/lib/demo/grid_list_demo.dart +++ b/examples/material_gallery/lib/demo/grid_list_demo.dart @@ -3,11 +3,42 @@ // found in the LICENSE file. import 'dart:collection'; -import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import '../gallery/demo.dart'; + +const String _kExampleCode = +"""// Creates a scrollable grid list with images +// loaded from the web. +new ScrollableGrid( + delegate: new FixedColumnCountGridDelegate( + columnCount: 3, + tileAspectRatio: 1.0, + padding: const EdgeInsets.all(4.0), + columnSpacing: 4.0, + rowSpacing: 4.0 + ), + children: [ + 'https://example.com/image-0.jpg', + 'https://example.com/image-1.jpg', + 'https://example.com/image-2.jpg', + ... + 'https://example.com/image-n.jpg' + ].map((String url) { + return new GridTile( + footer: new GridTileBar( + title: new Text(url) + ), + child: new NetworkImage( + src: url, + fit: ImageFit.cover + ) + ); + }) +);"""; + enum GridDemoTileStyle { imageOnly, oneLine, @@ -15,89 +46,36 @@ enum GridDemoTileStyle { } class Photo { - const Photo({ this.assetName, this.title, this.caption }); + Photo({ this.assetName, this.title, this.caption, this.isFavorite: false }); final String assetName; - final String title; final String caption; - bool get isValid => assetName != null; -} + bool isFavorite; -final List photos = [ - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_0.jpg', - title: 'Philippines', - caption: 'Batad rice terraces' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_1.jpg', - title: 'Italy', - caption: 'Ceresole Reale' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_2.jpg', - title: 'Somewhere', - caption: 'Beautiful mountains' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_3.jpg', - title: 'A place', - caption: 'Beautiful hills' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_4.jpg', - title: 'New Zealand', - caption: 'View from the van' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_5.jpg', - title: 'Autumn', - caption: 'The golden season' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_6.jpg', - title: 'Germany', - caption: 'Englischer Garten' - ), - const Photo(assetName: - 'packages/flutter_gallery_assets/landscape_7.jpg', - title: 'A country', - caption: 'Grass fields' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_8.jpg', - title: 'Mountain country', - caption: 'River forest' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_9.jpg', - title: 'Alpine place', - caption: 'Green hills' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_10.jpg', - title: 'Desert land', - caption: 'Blue skies' - ), - const Photo( - assetName: 'packages/flutter_gallery_assets/landscape_11.jpg', - title: 'Narnia', - caption: 'Rocks and rivers' - ), -]; + bool get isValid => assetName != null && title != null && caption != null && isFavorite != null; +} const String photoHeroTag = 'Photo'; +typedef void PhotoFavoriteCallback(Photo photo); + class GridDemoPhotoItem extends StatelessWidget { - GridDemoPhotoItem({ Key key, this.photo, this.tileStyle }) : super(key: key) { + GridDemoPhotoItem({ + Key key, + this.photo, + this.tileStyle, + this.onPressedFavorite + }) : super(key: key) { assert(photo != null && photo.isValid); assert(tileStyle != null); + assert(onPressedFavorite != null); } final Photo photo; final GridDemoTileStyle tileStyle; + final PhotoFavoriteCallback onPressedFavorite; void showPhoto(BuildContext context) { Key photoKey = new Key(photo.assetName); @@ -141,6 +119,8 @@ class GridDemoPhotoItem extends StatelessWidget { ) ); + IconData icon = photo.isFavorite ? Icons.star : Icons.star_border; + switch(tileStyle) { case GridDemoTileStyle.imageOnly: return image; @@ -148,8 +128,12 @@ class GridDemoPhotoItem extends StatelessWidget { case GridDemoTileStyle.oneLine: return new GridTile( header: new GridTileBar( - backgroundColor: Colors.black.withAlpha(0x08), - leading: new Icon(icon: Icons.info, color: Colors.white70), + backgroundColor: Colors.black45, + leading: new IconButton( + icon: icon, + color: Colors.white, + onPressed: () { onPressedFavorite(photo); } + ), title: new Text(photo.title) ), child: image @@ -158,10 +142,14 @@ class GridDemoPhotoItem extends StatelessWidget { case GridDemoTileStyle.twoLine: return new GridTile( footer: new GridTileBar( - backgroundColor: Colors.black.withAlpha(0x08), + backgroundColor: Colors.black45, title: new Text(photo.title), subtitle: new Text(photo.caption), - trailing: new Icon(icon: Icons.info, color: Colors.white70) + trailing: new IconButton( + icon: icon, + color: Colors.white, + onPressed: () { onPressedFavorite(photo); } + ) ), child: image ); @@ -169,46 +157,6 @@ class GridDemoPhotoItem extends StatelessWidget { } } -class GridListDemoGridDelegate extends FixedColumnCountGridDelegate { - GridListDemoGridDelegate({ - this.columnCount, - double columnSpacing: 0.0, - double rowSpacing: 0.0, - EdgeInsets padding: EdgeInsets.zero, - this.tileHeightFactor: 2.75 - }) : super(columnSpacing: columnSpacing, rowSpacing: rowSpacing, padding: padding) { - assert(columnCount != null && columnCount >= 0); - assert(tileHeightFactor != null && tileHeightFactor > 0.0); - } - - @override - final int columnCount; - - final double tileHeightFactor; - - @override - GridSpecification getGridSpecification(BoxConstraints constraints, int childCount) { - assert(constraints.maxWidth < double.INFINITY); - assert(constraints.maxHeight < double.INFINITY); - return new GridSpecification.fromRegularTiles( - tileWidth: math.max(0.0, constraints.maxWidth - padding.horizontal + columnSpacing) / columnCount, - tileHeight: constraints.maxHeight / tileHeightFactor, - columnCount: columnCount, - rowCount: (childCount / columnCount).ceil(), - columnSpacing: columnSpacing, - rowSpacing: rowSpacing, - padding: padding - ); - } - - @override - bool shouldRelayout(GridListDemoGridDelegate oldDelegate) { - return columnCount != oldDelegate.columnCount - || tileHeightFactor != oldDelegate.tileHeightFactor - || super.shouldRelayout(oldDelegate); - } -} - class GridListDemo extends StatefulWidget { GridListDemo({ Key key }) : super(key: key); @@ -219,6 +167,69 @@ class GridListDemo extends StatefulWidget { class GridListDemoState extends State { GridDemoTileStyle tileStyle = GridDemoTileStyle.twoLine; + List photos = [ + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_0.jpg', + title: 'Philippines', + caption: 'Batad rice terraces' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_1.jpg', + title: 'Italy', + caption: 'Ceresole Reale' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_2.jpg', + title: 'Somewhere', + caption: 'Beautiful mountains' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_3.jpg', + title: 'A place', + caption: 'Beautiful hills' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_4.jpg', + title: 'New Zealand', + caption: 'View from the van' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_5.jpg', + title: 'Autumn', + caption: 'The golden season' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_6.jpg', + title: 'Germany', + caption: 'Englischer Garten' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_7.jpg', + title: 'A country', + caption: 'Grass fields' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_8.jpg', + title: 'Mountain country', + caption: 'River forest' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_9.jpg', + title: 'Alpine place', + caption: 'Green hills' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_10.jpg', + title: 'Desert land', + caption: 'Blue skies' + ), + new Photo( + assetName: 'packages/flutter_gallery_assets/landscape_11.jpg', + title: 'Narnia', + caption: 'Rocks and rivers' + ), + ]; + void showTileStyleMenu(BuildContext context) { final List> items = >[ new PopupMenuItem( @@ -265,18 +276,34 @@ class GridListDemoState extends State { ) ] ), - body: new ScrollableGrid( - delegate: new GridListDemoGridDelegate( - columnCount: (orientation == Orientation.portrait) ? 2 : 3, - rowSpacing: 4.0, - columnSpacing: 4.0, - padding: const EdgeInsets.all(4.0), - tileHeightFactor: (orientation == Orientation.portrait) ? 2.75 : 1.75 - ), - children: photos.map((Photo photo) { - return new GridDemoPhotoItem(photo: photo, tileStyle: tileStyle); - }) - .toList() + body: new Column( + children: [ + new Flexible( + child: new ScrollableGrid( + delegate: new FixedColumnCountGridDelegate( + columnCount: (orientation == Orientation.portrait) ? 2 : 3, + rowSpacing: 4.0, + columnSpacing: 4.0, + padding: const EdgeInsets.all(4.0), + tileAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3 + ), + children: photos.map((Photo photo) { + return new GridDemoPhotoItem( + photo: photo, + tileStyle: tileStyle, + onPressedFavorite: (Photo photo) { + setState(() { + photo.isFavorite = !photo.isFavorite; + }); + } + ); + }) + ) + ), + new DemoBottomBar( + exampleCode: _kExampleCode + ) + ] ) ); }