Improvements to the Grid list demo (#3315)
* Improvements to the Grid list demo * More nits and fixes to grid demo in gallery
This commit is contained in:
parent
cf8d79d027
commit
ec85af59b4
@ -3,11 +3,42 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:math' as math;
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.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: <String>[
|
||||||
|
'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 {
|
enum GridDemoTileStyle {
|
||||||
imageOnly,
|
imageOnly,
|
||||||
oneLine,
|
oneLine,
|
||||||
@ -15,89 +46,36 @@ enum GridDemoTileStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Photo {
|
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 assetName;
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
final String caption;
|
final String caption;
|
||||||
|
|
||||||
bool get isValid => assetName != null;
|
bool isFavorite;
|
||||||
}
|
|
||||||
|
|
||||||
final List<Photo> photos = <Photo>[
|
bool get isValid => assetName != null && title != null && caption != null && isFavorite != null;
|
||||||
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'
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
const String photoHeroTag = 'Photo';
|
const String photoHeroTag = 'Photo';
|
||||||
|
|
||||||
|
typedef void PhotoFavoriteCallback(Photo photo);
|
||||||
|
|
||||||
class GridDemoPhotoItem extends StatelessWidget {
|
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(photo != null && photo.isValid);
|
||||||
assert(tileStyle != null);
|
assert(tileStyle != null);
|
||||||
|
assert(onPressedFavorite != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Photo photo;
|
final Photo photo;
|
||||||
final GridDemoTileStyle tileStyle;
|
final GridDemoTileStyle tileStyle;
|
||||||
|
final PhotoFavoriteCallback onPressedFavorite;
|
||||||
|
|
||||||
void showPhoto(BuildContext context) {
|
void showPhoto(BuildContext context) {
|
||||||
Key photoKey = new Key(photo.assetName);
|
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) {
|
switch(tileStyle) {
|
||||||
case GridDemoTileStyle.imageOnly:
|
case GridDemoTileStyle.imageOnly:
|
||||||
return image;
|
return image;
|
||||||
@ -148,8 +128,12 @@ class GridDemoPhotoItem extends StatelessWidget {
|
|||||||
case GridDemoTileStyle.oneLine:
|
case GridDemoTileStyle.oneLine:
|
||||||
return new GridTile(
|
return new GridTile(
|
||||||
header: new GridTileBar(
|
header: new GridTileBar(
|
||||||
backgroundColor: Colors.black.withAlpha(0x08),
|
backgroundColor: Colors.black45,
|
||||||
leading: new Icon(icon: Icons.info, color: Colors.white70),
|
leading: new IconButton(
|
||||||
|
icon: icon,
|
||||||
|
color: Colors.white,
|
||||||
|
onPressed: () { onPressedFavorite(photo); }
|
||||||
|
),
|
||||||
title: new Text(photo.title)
|
title: new Text(photo.title)
|
||||||
),
|
),
|
||||||
child: image
|
child: image
|
||||||
@ -158,10 +142,14 @@ class GridDemoPhotoItem extends StatelessWidget {
|
|||||||
case GridDemoTileStyle.twoLine:
|
case GridDemoTileStyle.twoLine:
|
||||||
return new GridTile(
|
return new GridTile(
|
||||||
footer: new GridTileBar(
|
footer: new GridTileBar(
|
||||||
backgroundColor: Colors.black.withAlpha(0x08),
|
backgroundColor: Colors.black45,
|
||||||
title: new Text(photo.title),
|
title: new Text(photo.title),
|
||||||
subtitle: new Text(photo.caption),
|
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
|
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 {
|
class GridListDemo extends StatefulWidget {
|
||||||
GridListDemo({ Key key }) : super(key: key);
|
GridListDemo({ Key key }) : super(key: key);
|
||||||
|
|
||||||
@ -219,6 +167,69 @@ class GridListDemo extends StatefulWidget {
|
|||||||
class GridListDemoState extends State<GridListDemo> {
|
class GridListDemoState extends State<GridListDemo> {
|
||||||
GridDemoTileStyle tileStyle = GridDemoTileStyle.twoLine;
|
GridDemoTileStyle tileStyle = GridDemoTileStyle.twoLine;
|
||||||
|
|
||||||
|
List<Photo> photos = <Photo>[
|
||||||
|
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) {
|
void showTileStyleMenu(BuildContext context) {
|
||||||
final List<PopupMenuItem<GridDemoTileStyle>> items = <PopupMenuItem<GridDemoTileStyle>>[
|
final List<PopupMenuItem<GridDemoTileStyle>> items = <PopupMenuItem<GridDemoTileStyle>>[
|
||||||
new PopupMenuItem<GridDemoTileStyle>(
|
new PopupMenuItem<GridDemoTileStyle>(
|
||||||
@ -265,18 +276,34 @@ class GridListDemoState extends State<GridListDemo> {
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
body: new ScrollableGrid(
|
body: new Column(
|
||||||
delegate: new GridListDemoGridDelegate(
|
children: <Widget>[
|
||||||
columnCount: (orientation == Orientation.portrait) ? 2 : 3,
|
new Flexible(
|
||||||
rowSpacing: 4.0,
|
child: new ScrollableGrid(
|
||||||
columnSpacing: 4.0,
|
delegate: new FixedColumnCountGridDelegate(
|
||||||
padding: const EdgeInsets.all(4.0),
|
columnCount: (orientation == Orientation.portrait) ? 2 : 3,
|
||||||
tileHeightFactor: (orientation == Orientation.portrait) ? 2.75 : 1.75
|
rowSpacing: 4.0,
|
||||||
),
|
columnSpacing: 4.0,
|
||||||
children: photos.map((Photo photo) {
|
padding: const EdgeInsets.all(4.0),
|
||||||
return new GridDemoPhotoItem(photo: photo, tileStyle: tileStyle);
|
tileAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3
|
||||||
})
|
),
|
||||||
.toList()
|
children: photos.map((Photo photo) {
|
||||||
|
return new GridDemoPhotoItem(
|
||||||
|
photo: photo,
|
||||||
|
tileStyle: tileStyle,
|
||||||
|
onPressedFavorite: (Photo photo) {
|
||||||
|
setState(() {
|
||||||
|
photo.isFavorite = !photo.isFavorite;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
),
|
||||||
|
new DemoBottomBar(
|
||||||
|
exampleCode: _kExampleCode
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user