Commit 77cd8ee4 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Reproduce the Shrine home page portrait grid layout (#4779)

parent 41d63035
...@@ -18,6 +18,47 @@ const double unitSize = kToolBarHeight; ...@@ -18,6 +18,47 @@ const double unitSize = kToolBarHeight;
final List<Product> _products = new List<Product>.from(allProducts()); final List<Product> _products = new List<Product>.from(allProducts());
final Map<Product, Order> _shoppingCart = <Product, Order>{}; final Map<Product, Order> _shoppingCart = <Product, Order>{};
// The Shrine home page arranges the product cards into two columns. The card
// on every 4th and 5th row spans two columns.
class ShrineGridDelegate extends GridDelegate {
int _rowAtIndex(int index) {
final int n = index ~/ 8;
return const <int>[0, 0, 1, 1, 2, 2, 3, 4][index - n * 8] + n * 5;
}
int _columnAtIndex(int index) {
return const <int>[0, 1, 0, 1, 0, 1, 0, 0][index % 8];
}
int _columnSpanAtIndex(int index) {
return const <int>[1, 1, 1, 1, 1, 1, 2, 2][index % 8];
}
@override
GridSpecification getGridSpecification(BoxConstraints constraints, int childCount) {
assert(childCount >= 0);
return new GridSpecification.fromRegularTiles(
tileWidth: constraints.maxWidth / 2.0 - 8.0,
tileHeight: constraints.maxWidth * 0.67,
columnCount: 2,
rowCount: childCount == 0 ? 0 : _rowAtIndex(childCount - 1) + 1,
rowSpacing: 8.0,
columnSpacing: 8.0
);
}
@override
GridChildPlacement getChildPlacement(GridSpecification specification, int index, Object placementData) {
assert(index >= 0);
return new GridChildPlacement(
column: _columnAtIndex(index),
row: _rowAtIndex(index),
columnSpan: _columnSpanAtIndex(index),
rowSpan: 1
);
}
}
/// Displays the Vendor's name and avatar. /// Displays the Vendor's name and avatar.
class VendorItem extends StatelessWidget { class VendorItem extends StatelessWidget {
VendorItem({ Key key, this.vendor }) : super(key: key) { VendorItem({ Key key, this.vendor }) : super(key: key) {
...@@ -65,7 +106,7 @@ abstract class PriceItem extends StatelessWidget { ...@@ -65,7 +106,7 @@ abstract class PriceItem extends StatelessWidget {
Widget buildItem(BuildContext context, TextStyle style, EdgeInsets padding) { Widget buildItem(BuildContext context, TextStyle style, EdgeInsets padding) {
BoxDecoration decoration; BoxDecoration decoration;
if (_shoppingCart[product] != null) if (_shoppingCart[product] != null)
decoration = new BoxDecoration(backgroundColor: const Color(0xFFFFE0E0)); decoration = new BoxDecoration(backgroundColor: ShrineTheme.of(context).priceHighlightColor);
return new Container( return new Container(
padding: padding, padding: padding,
...@@ -140,9 +181,11 @@ class FeatureItem extends StatelessWidget { ...@@ -140,9 +181,11 @@ class FeatureItem extends StatelessWidget {
final ShrineTheme theme = ShrineTheme.of(context); final ShrineTheme theme = ShrineTheme.of(context);
return new AspectRatio( return new AspectRatio(
aspectRatio: 3.0 / 3.5, aspectRatio: 3.0 / 3.5,
child: new Material( child: new Container(
type: MaterialType.card, decoration: new BoxDecoration(
elevation: 1, backgroundColor: theme.cardBackgroundColor,
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Column( child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
...@@ -261,6 +304,7 @@ class ShrineHome extends StatefulWidget { ...@@ -261,6 +304,7 @@ class ShrineHome extends StatefulWidget {
class _ShrineHomeState extends State<ShrineHome> { class _ShrineHomeState extends State<ShrineHome> {
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: 'Order page'); static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: 'Order page');
static final GridDelegate gridDelegate = new ShrineGridDelegate();
void handleCompletedOrder(Order completedOrder) { void handleCompletedOrder(Order completedOrder) {
assert(completedOrder.product != null); assert(completedOrder.product != null);
...@@ -300,24 +344,20 @@ class _ShrineHomeState extends State<ShrineHome> { ...@@ -300,24 +344,20 @@ class _ShrineHomeState extends State<ShrineHome> {
child: new RepaintBoundary( child: new RepaintBoundary(
child: new Column( child: new Column(
children: <Widget>[ children: <Widget>[
new Container( new FeatureItem(product: featured),
margin: new EdgeInsets.only(bottom: 8.0), new Padding(
child: new FeatureItem(product: featured) padding: const EdgeInsets.all(16.0),
), child: new CustomGrid(
new FixedColumnCountGrid( delegate: gridDelegate,
columnCount: 2, children: _products.map((Product product) {
rowSpacing: 8.0, return new RepaintBoundary(
columnSpacing: 8.0, child: new ProductItem(
padding: const EdgeInsets.all(8.0), product: product,
tileAspectRatio: 160.0 / 224.0, // width/height onPressed: () { showOrderPage(product); }
children: _products.map((Product product) { )
return new RepaintBoundary( );
child: new ProductItem( }).toList()
product: product, )
onPressed: () { showOrderPage(product); }
)
);
}).toList()
) )
] ]
) )
......
...@@ -83,17 +83,18 @@ class ShrinePageState extends State<ShrinePage> { ...@@ -83,17 +83,18 @@ class ShrinePageState extends State<ShrinePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ShrineTheme theme = ShrineTheme.of(context);
return new Scaffold( return new Scaffold(
key: config.scaffoldKey, key: config.scaffoldKey,
appBar: new AppBar( appBar: new AppBar(
elevation: _appBarElevation, elevation: _appBarElevation,
backgroundColor: Theme.of(context).cardColor, backgroundColor: theme.appBarBackgroundColor,
iconTheme: Theme.of(context).iconTheme, iconTheme: Theme.of(context).iconTheme,
brightness: Brightness.light, brightness: Brightness.light,
flexibleSpace: new Container( flexibleSpace: new Container(
decoration: new BoxDecoration( decoration: new BoxDecoration(
border: new Border( border: new Border(
bottom: new BorderSide(color: const Color(0xFFD9D9D9)) bottom: new BorderSide(color: theme.dividerColor)
) )
) )
), ),
......
...@@ -30,6 +30,11 @@ class ShrineTheme extends InheritedWidget { ...@@ -30,6 +30,11 @@ class ShrineTheme extends InheritedWidget {
assert(child != null); assert(child != null);
} }
final Color cardBackgroundColor = Colors.white;
final Color appBarBackgroundColor = Colors.white;
final Color dividerColor = const Color(0xFFD9D9D9);
final Color priceHighlightColor = const Color(0xFFFFE0E0);
final TextStyle appBarTitleStyle = robotoRegular20(Colors.black87); final TextStyle appBarTitleStyle = robotoRegular20(Colors.black87);
final TextStyle vendorItemStyle = robotoRegular12(const Color(0xFF81959D)); final TextStyle vendorItemStyle = robotoRegular12(const Color(0xFF81959D));
final TextStyle priceStyle = robotoRegular14(Colors.black87); final TextStyle priceStyle = robotoRegular14(Colors.black87);
......
...@@ -24,6 +24,7 @@ export 'package:flutter/rendering.dart' show ...@@ -24,6 +24,7 @@ export 'package:flutter/rendering.dart' show
FlowDelegate, FlowDelegate,
FlowPaintingContext, FlowPaintingContext,
FractionalOffsetTween, FractionalOffsetTween,
GridChildPlacement,
GridDelegate, GridDelegate,
GridDelegateWithInOrderChildPlacement, GridDelegateWithInOrderChildPlacement,
GridSpecification, GridSpecification,
......
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