Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
9192f672
Commit
9192f672
authored
Mar 27, 2017
by
Hans Muller
Committed by
GitHub
Mar 27, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Shrine gallery demo: support for landscape layout (#9025)
parent
23981f59
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
274 additions
and
200 deletions
+274
-200
shrine_home.dart
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
+93
-96
shrine_order.dart
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
+181
-104
No files found.
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
View file @
9192f672
...
...
@@ -47,8 +47,8 @@ int _columnSpanAtIndex(int index) {
// The Shrine home page arranges the product cards into two columns. The card
// on every 4th and 5th row spans two columns.
class
ShrineGridLayout
extends
SliverGridLayout
{
const
ShrineGridLayout
({
class
_
ShrineGridLayout
extends
SliverGridLayout
{
const
_
ShrineGridLayout
({
@required
this
.
rowStride
,
@required
this
.
columnStride
,
@required
this
.
tileHeight
,
...
...
@@ -95,14 +95,14 @@ class ShrineGridLayout extends SliverGridLayout {
}
}
class
ShrineGridDelegate
extends
SliverGridDelegate
{
class
_
ShrineGridDelegate
extends
SliverGridDelegate
{
static
const
double
_kSpacing
=
8.0
;
@override
SliverGridLayout
getLayout
(
SliverConstraints
constraints
)
{
final
double
tileWidth
=
(
constraints
.
crossAxisExtent
-
_kSpacing
)
/
2.0
;
final
double
tileHeight
=
40.0
+
144.0
+
40.0
;
return
new
ShrineGridLayout
(
return
new
_
ShrineGridLayout
(
tileWidth:
tileWidth
,
tileHeight:
tileHeight
,
rowStride:
tileHeight
+
_kSpacing
,
...
...
@@ -114,9 +114,9 @@ class ShrineGridDelegate extends SliverGridDelegate {
bool
shouldRelayout
(
covariant
SliverGridDelegate
oldDelegate
)
=>
false
;
}
//
/
Displays the Vendor's name and avatar.
class
VendorItem
extends
StatelessWidget
{
VendorItem
({
Key
key
,
this
.
vendor
})
:
super
(
key:
key
)
{
// Displays the Vendor's name and avatar.
class
_
VendorItem
extends
StatelessWidget
{
_
VendorItem
({
Key
key
,
this
.
vendor
})
:
super
(
key:
key
)
{
assert
(
vendor
!=
null
);
}
...
...
@@ -145,10 +145,10 @@ class VendorItem extends StatelessWidget {
}
}
//
/ Displays the product's price. If the product is in the shopping cart the background
//
/
is highlighted.
abstract
class
PriceItem
extends
StatelessWidget
{
PriceItem
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
//
Displays the product's price. If the product is in the shopping cart then the
//
background
is highlighted.
abstract
class
_
PriceItem
extends
StatelessWidget
{
_
PriceItem
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
assert
(
product
!=
null
);
}
...
...
@@ -167,8 +167,8 @@ abstract class PriceItem extends StatelessWidget {
}
}
class
ProductPriceItem
extends
PriceItem
{
ProductPriceItem
({
Key
key
,
Product
product
})
:
super
(
key:
key
,
product:
product
);
class
_ProductPriceItem
extends
_
PriceItem
{
_
ProductPriceItem
({
Key
key
,
Product
product
})
:
super
(
key:
key
,
product:
product
);
@override
Widget
build
(
BuildContext
context
)
{
...
...
@@ -180,8 +180,8 @@ class ProductPriceItem extends PriceItem {
}
}
class
FeaturePriceItem
extends
PriceItem
{
FeaturePriceItem
({
Key
key
,
Product
product
})
:
super
(
key:
key
,
product:
product
);
class
_FeaturePriceItem
extends
_
PriceItem
{
_
FeaturePriceItem
({
Key
key
,
Product
product
})
:
super
(
key:
key
,
product:
product
);
@override
Widget
build
(
BuildContext
context
)
{
...
...
@@ -193,34 +193,54 @@ class FeaturePriceItem extends PriceItem {
}
}
/// Layout the main left and right elements of a FeatureItem.
class
FeatureLayout
extends
MultiChildLayoutDelegate
{
FeatureLayout
();
class
_HeadingLayout
extends
MultiChildLayoutDelegate
{
_HeadingLayout
();
static
final
String
left
=
'left'
;
static
final
String
right
=
'right'
;
static
final
String
price
=
'price'
;
static
final
String
image
=
'image'
;
static
final
String
title
=
'title'
;
static
final
String
description
=
'description'
;
static
final
String
vendor
=
'vendor'
;
// Horizontally: the feature product image appears on the left and
// occupies 50% of the available width; the feature product's
// description apepars on the right and occupies 50% of the available
// width + unitSize. The left and right widgets overlap and the right
// widget is stacked on top.
@override
void
performLayout
(
Size
size
)
{
final
Size
priceSize
=
layoutChild
(
price
,
new
BoxConstraints
.
loose
(
size
));
positionChild
(
price
,
new
Offset
(
size
.
width
-
priceSize
.
width
,
0.0
));
final
double
halfWidth
=
size
.
width
/
2.0
;
layoutChild
(
left
,
new
BoxConstraints
.
tightFor
(
width:
halfWidth
,
height:
size
.
height
));
positionChild
(
left
,
Offset
.
zero
);
layoutChild
(
right
,
new
BoxConstraints
.
expand
(
width:
halfWidth
+
unitSize
,
height:
size
.
height
));
positionChild
(
right
,
new
Offset
(
halfWidth
-
unitSize
,
0.0
));
final
double
halfHeight
=
size
.
height
/
2.0
;
final
double
halfUnit
=
unitSize
/
2.0
;
const
double
margin
=
16.0
;
final
Size
imageSize
=
layoutChild
(
image
,
new
BoxConstraints
.
loose
(
size
));
final
double
imageX
=
imageSize
.
width
<
halfWidth
-
halfUnit
?
halfWidth
/
2.0
-
imageSize
.
width
/
2.0
-
halfUnit
:
halfWidth
-
imageSize
.
width
;
positionChild
(
image
,
new
Offset
(
imageX
,
halfHeight
-
imageSize
.
height
/
2.0
));
final
double
maxTitleWidth
=
halfWidth
+
unitSize
-
margin
;
final
BoxConstraints
titleBoxConstraints
=
new
BoxConstraints
(
maxWidth:
maxTitleWidth
);
final
Size
titleSize
=
layoutChild
(
title
,
titleBoxConstraints
);
final
double
titleX
=
halfWidth
-
unitSize
;
final
double
titleY
=
halfHeight
-
titleSize
.
height
;
positionChild
(
title
,
new
Offset
(
titleX
,
titleY
));
final
Size
descriptionSize
=
layoutChild
(
description
,
titleBoxConstraints
);
final
double
descriptionY
=
titleY
+
titleSize
.
height
+
margin
;
positionChild
(
description
,
new
Offset
(
titleX
,
descriptionY
));
layoutChild
(
vendor
,
titleBoxConstraints
);
final
double
vendorY
=
descriptionY
+
descriptionSize
.
height
+
margin
;
positionChild
(
vendor
,
new
Offset
(
titleX
,
vendorY
));
}
@override
bool
shouldRelayout
(
Feature
Layout
oldDelegate
)
=>
false
;
bool
shouldRelayout
(
_Heading
Layout
oldDelegate
)
=>
false
;
}
//
/
A card that highlights the "featured" catalog item.
class
FeatureItem
extends
StatelessWidget
{
FeatureItem
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
// A card that highlights the "featured" catalog item.
class
_Heading
extends
StatelessWidget
{
_Heading
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
assert
(
product
.
featureTitle
!=
null
);
assert
(
product
.
featureDescription
!=
null
);
}
...
...
@@ -229,63 +249,39 @@ class FeatureItem extends StatelessWidget {
@override
Widget
build
(
BuildContext
context
)
{
final
Size
screenSize
=
MediaQuery
.
of
(
context
).
size
;
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
AspectRatio
(
aspectRatio:
3.0
/
3.5
,
return
new
SizedBox
(
height:
screenSize
.
width
>
screenSize
.
height
?
(
screenSize
.
height
-
kToolbarHeight
)
*
0.85
:
(
screenSize
.
height
-
kToolbarHeight
)
*
0.70
,
child:
new
Container
(
decoration:
new
BoxDecoration
(
backgroundColor:
theme
.
cardBackgroundColor
,
border:
new
Border
(
bottom:
new
BorderSide
(
color:
theme
.
dividerColor
)),
),
child:
new
C
olumn
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
child:
new
C
ustomMultiChildLayout
(
delegate:
new
_HeadingLayout
()
,
children:
<
Widget
>[
new
SizedBox
(
height:
unitSize
,
child:
new
Align
(
alignment:
FractionalOffset
.
topRight
,
child:
new
FeaturePriceItem
(
product:
product
),
),
new
LayoutId
(
id:
_HeadingLayout
.
price
,
child:
new
_FeaturePriceItem
(
product:
product
),
),
new
Expanded
(
child:
new
CustomMultiChildLayout
(
delegate:
new
FeatureLayout
(),
children:
<
Widget
>[
new
LayoutId
(
id:
FeatureLayout
.
left
,
child:
new
ClipRect
(
child:
new
OverflowBox
(
minWidth:
340.0
,
maxWidth:
340.0
,
minHeight:
340.0
,
maxHeight:
340.0
,
alignment:
FractionalOffset
.
topRight
,
child:
new
Image
.
asset
(
product
.
imageAsset
,
fit:
BoxFit
.
cover
),
),
),
),
new
LayoutId
(
id:
FeatureLayout
.
right
,
child:
new
Padding
(
padding:
const
EdgeInsets
.
only
(
right:
16.0
),
child:
new
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
new
Padding
(
padding:
const
EdgeInsets
.
only
(
top:
18.0
),
child:
new
Text
(
product
.
featureTitle
,
style:
theme
.
featureTitleStyle
),
),
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
vertical:
16.0
),
child:
new
Text
(
product
.
featureDescription
,
style:
theme
.
featureStyle
),
),
new
VendorItem
(
vendor:
product
.
vendor
),
],
),
),
),
],
),
new
LayoutId
(
id:
_HeadingLayout
.
image
,
child:
new
Image
.
asset
(
product
.
imageAsset
,
fit:
BoxFit
.
cover
),
),
new
LayoutId
(
id:
_HeadingLayout
.
title
,
child:
new
Text
(
product
.
featureTitle
,
style:
theme
.
featureTitleStyle
),
),
new
LayoutId
(
id:
_HeadingLayout
.
description
,
child:
new
Text
(
product
.
featureDescription
,
style:
theme
.
featureStyle
),
),
new
LayoutId
(
id:
_HeadingLayout
.
vendor
,
child:
new
_VendorItem
(
vendor:
product
.
vendor
),
),
],
),
...
...
@@ -294,9 +290,10 @@ class FeatureItem extends StatelessWidget {
}
}
/// A card that displays a product's image, price, and vendor.
class
ProductItem
extends
StatelessWidget
{
ProductItem
({
Key
key
,
this
.
product
,
this
.
onPressed
})
:
super
(
key:
key
)
{
// A card that displays a product's image, price, and vendor. The _ProductItem
// cards appear in a grid below the heading.
class
_ProductItem
extends
StatelessWidget
{
_ProductItem
({
Key
key
,
this
.
product
,
this
.
onPressed
})
:
super
(
key:
key
)
{
assert
(
product
!=
null
);
}
...
...
@@ -312,7 +309,7 @@ class ProductItem extends StatelessWidget {
children:
<
Widget
>[
new
Align
(
alignment:
FractionalOffset
.
centerRight
,
child:
new
ProductPriceItem
(
product:
product
),
child:
new
_
ProductPriceItem
(
product:
product
),
),
new
Container
(
width:
144.0
,
...
...
@@ -325,7 +322,7 @@ class ProductItem extends StatelessWidget {
),
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
8.0
),
child:
new
VendorItem
(
vendor:
product
.
vendor
),
child:
new
_
VendorItem
(
vendor:
product
.
vendor
),
),
],
),
...
...
@@ -339,18 +336,18 @@ class ProductItem extends StatelessWidget {
}
}
//
/ The Shrine app's home page. Displays the featured item above all of the
//
/ product items arranged in two column
s.
//
The Shrine app's home page. Displays the featured item above a grid
//
of the product item
s.
class
ShrineHome
extends
StatefulWidget
{
@override
_ShrineHomeState
createState
()
=>
new
_ShrineHomeState
();
}
class
_ShrineHomeState
extends
State
<
ShrineHome
>
{
static
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>(
debugLabel:
'Shrine Home'
);
static
final
ShrineGridDelegate
gridDelegate
=
new
ShrineGridDelegate
();
static
final
GlobalKey
<
ScaffoldState
>
_
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>(
debugLabel:
'Shrine Home'
);
static
final
_ShrineGridDelegate
gridDelegate
=
new
_
ShrineGridDelegate
();
Future
<
Null
>
showOrderPage
(
Product
product
)
async
{
Future
<
Null
>
_
showOrderPage
(
Product
product
)
async
{
final
Order
order
=
_shoppingCart
[
product
]
??
new
Order
(
product:
product
);
final
Order
completedOrder
=
await
Navigator
.
push
(
context
,
new
ShrineOrderRoute
(
order:
order
,
...
...
@@ -371,13 +368,13 @@ class _ShrineHomeState extends State<ShrineHome> {
Widget
build
(
BuildContext
context
)
{
final
Product
featured
=
_products
.
firstWhere
((
Product
product
)
=>
product
.
featureDescription
!=
null
);
return
new
ShrinePage
(
scaffoldKey:
scaffoldKey
,
scaffoldKey:
_
scaffoldKey
,
products:
_products
,
shoppingCart:
_shoppingCart
,
body:
new
CustomScrollView
(
slivers:
<
Widget
>[
new
SliverToBoxAdapter
(
child:
new
FeatureItem
(
product:
featured
),
child:
new
_Heading
(
product:
featured
),
),
new
SliverPadding
(
padding:
const
EdgeInsets
.
all
(
16.0
),
...
...
@@ -385,9 +382,9 @@ class _ShrineHomeState extends State<ShrineHome> {
gridDelegate:
gridDelegate
,
delegate:
new
SliverChildListDelegate
(
_products
.
map
((
Product
product
)
{
return
new
ProductItem
(
return
new
_
ProductItem
(
product:
product
,
onPressed:
()
{
showOrderPage
(
product
);
},
onPressed:
()
{
_
showOrderPage
(
product
);
},
);
}).
toList
(),
),
...
...
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
View file @
9192f672
...
...
@@ -9,10 +9,133 @@ import 'shrine_page.dart';
import
'shrine_theme.dart'
;
import
'shrine_types.dart'
;
/// Describes a product and vendor in detail, supports specifying
/// a order quantity (0-5). Appears at the top of the OrderPage.
class
OrderItem
extends
StatelessWidget
{
OrderItem
({
Key
key
,
this
.
product
,
this
.
quantity
,
this
.
quantityChanged
})
:
super
(
key:
key
)
{
// Displays the product title's, description, and order quantity dropdown.
class
_ProductItem
extends
StatelessWidget
{
_ProductItem
({
Key
key
,
this
.
product
,
this
.
quantity
,
this
.
onChanged
})
:
super
(
key:
key
)
{
assert
(
product
!=
null
);
assert
(
quantity
!=
null
);
assert
(
onChanged
!=
null
);
}
final
Product
product
;
final
int
quantity
;
final
ValueChanged
<
int
>
onChanged
;
@override
Widget
build
(
BuildContext
context
)
{
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
Text
(
product
.
name
,
style:
theme
.
featureTitleStyle
),
const
SizedBox
(
height:
24.0
),
new
Text
(
product
.
description
,
style:
theme
.
featureStyle
),
const
SizedBox
(
height:
16.0
),
new
Padding
(
padding:
const
EdgeInsets
.
only
(
top:
8.0
,
bottom:
8.0
,
right:
88.0
),
child:
new
DropdownButtonHideUnderline
(
child:
new
Container
(
decoration:
new
BoxDecoration
(
border:
new
Border
.
all
(
color:
const
Color
(
0xFFD9D9D9
),
),
),
child:
new
DropdownButton
<
int
>(
items:
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
].
map
((
int
value
)
{
return
new
DropdownMenuItem
<
int
>(
value:
value
,
child:
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
8.0
),
child:
new
Text
(
'Quantity
$value
'
,
style:
theme
.
quantityMenuStyle
),
),
);
}).
toList
(),
value:
quantity
,
onChanged:
onChanged
,
),
),
),
),
],
);
}
}
// Vendor name and description
class
_VendorItem
extends
StatelessWidget
{
_VendorItem
({
Key
key
,
this
.
vendor
})
:
super
(
key:
key
)
{
assert
(
vendor
!=
null
);
}
final
Vendor
vendor
;
@override
Widget
build
(
BuildContext
context
)
{
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
SizedBox
(
height:
24.0
,
child:
new
Align
(
alignment:
FractionalOffset
.
bottomLeft
,
child:
new
Text
(
vendor
.
name
,
style:
theme
.
vendorTitleStyle
),
),
),
const
SizedBox
(
height:
16.0
),
new
Text
(
vendor
.
description
,
style:
theme
.
vendorStyle
),
],
);
}
}
// Layout the order page's heading: the product's image, the
// title/description/dropdown product item, and the vendor item.
class
_HeadingLayout
extends
MultiChildLayoutDelegate
{
_HeadingLayout
();
static
final
String
image
=
'image'
;
static
final
String
icon
=
'icon'
;
static
final
String
product
=
'product'
;
static
final
String
vendor
=
'vendor'
;
@override
void
performLayout
(
Size
size
)
{
const
double
margin
=
56.0
;
final
bool
landscape
=
size
.
width
>
size
.
height
;
final
double
imageWidth
=
(
landscape
?
size
.
width
/
2.0
:
size
.
width
)
-
margin
*
2.0
;
final
BoxConstraints
imageConstraints
=
new
BoxConstraints
(
maxHeight:
224.0
,
maxWidth:
imageWidth
);
final
Size
imageSize
=
layoutChild
(
image
,
imageConstraints
);
final
double
imageY
=
0.0
;
positionChild
(
image
,
new
Offset
(
margin
,
imageY
));
final
double
productWidth
=
landscape
?
size
.
width
/
2.0
:
size
.
width
-
margin
;
final
BoxConstraints
productConstraints
=
new
BoxConstraints
(
maxWidth:
productWidth
);
final
Size
productSize
=
layoutChild
(
product
,
productConstraints
);
final
double
productX
=
landscape
?
size
.
width
/
2.0
:
margin
;
final
double
productY
=
landscape
?
0.0
:
imageY
+
imageSize
.
height
+
16.0
;
positionChild
(
product
,
new
Offset
(
productX
,
productY
));
final
Size
iconSize
=
layoutChild
(
icon
,
new
BoxConstraints
.
loose
(
size
));
positionChild
(
icon
,
new
Offset
(
productX
-
iconSize
.
width
-
16.0
,
productY
+
8.0
));
final
double
vendorWidth
=
landscape
?
size
.
width
-
margin
:
productWidth
;
layoutChild
(
vendor
,
new
BoxConstraints
(
maxWidth:
vendorWidth
));
final
double
vendorX
=
landscape
?
margin
:
productX
;
final
double
vendorY
=
productY
+
productSize
.
height
+
16.0
;
positionChild
(
vendor
,
new
Offset
(
vendorX
,
vendorY
));
}
@override
bool
shouldRelayout
(
_HeadingLayout
oldDelegate
)
=>
true
;
}
// Describes a product and vendor in detail, supports specifying
// a order quantity (0-5). Appears at the top of the OrderPage.
class
_Heading
extends
StatelessWidget
{
_Heading
({
Key
key
,
this
.
product
,
this
.
quantity
,
this
.
quantityChanged
})
:
super
(
key:
key
)
{
assert
(
product
!=
null
);
assert
(
quantity
!=
null
&&
quantity
>=
0
&&
quantity
<=
5
);
}
...
...
@@ -23,92 +146,50 @@ class OrderItem extends StatelessWidget {
@override
Widget
build
(
BuildContext
context
)
{
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
Material
(
type:
MaterialType
.
card
,
elevation:
0
,
child:
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
16.0
,
top:
18.0
,
right:
16.0
,
bottom:
24.0
),
child:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
56.0
),
child:
new
SizedBox
(
width:
248.0
,
height:
248.0
,
final
Size
screenSize
=
MediaQuery
.
of
(
context
).
size
;
return
new
SizedBox
(
height:
(
screenSize
.
height
-
kToolbarHeight
)
*
1.35
,
child:
new
Material
(
type:
MaterialType
.
card
,
elevation:
0
,
child:
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
16.0
,
top:
18.0
,
right:
16.0
,
bottom:
24.0
),
child:
new
CustomMultiChildLayout
(
delegate:
new
_HeadingLayout
(),
children:
<
Widget
>[
new
LayoutId
(
id:
_HeadingLayout
.
image
,
child:
new
Hero
(
tag:
product
.
tag
,
child:
new
Image
.
asset
(
product
.
imageAsset
,
fit:
BoxFit
.
contain
),
child:
new
Image
.
asset
(
product
.
imageAsset
,
fit:
BoxFit
.
contain
,
alignment:
FractionalOffset
.
center
,
),
),
),
),
const
SizedBox
(
height:
24.0
),
new
Row
(
children:
<
Widget
>[
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
child:
new
Center
(
child:
new
Icon
(
Icons
.
info_outline
,
size:
24.0
,
color:
const
Color
(
0xFFFFE0E0
),
),
),
new
LayoutId
(
id:
_HeadingLayout
.
icon
,
child:
new
Icon
(
Icons
.
info_outline
,
size:
24.0
,
color:
const
Color
(
0xFFFFE0E0
),
),
new
Expanded
(
child:
new
Text
(
product
.
name
,
style:
theme
.
featureTitleStyle
),
),
new
LayoutId
(
id:
_HeadingLayout
.
product
,
child:
new
_ProductItem
(
product:
product
,
quantity:
quantity
,
onChanged:
quantityChanged
,
),
],
),
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
56.0
),
child:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
const
SizedBox
(
height:
24.0
),
new
Text
(
product
.
description
,
style:
theme
.
featureStyle
),
const
SizedBox
(
height:
16.0
),
new
Padding
(
padding:
const
EdgeInsets
.
only
(
top:
8.0
,
bottom:
8.0
,
right:
88.0
),
child:
new
DropdownButtonHideUnderline
(
child:
new
Container
(
decoration:
new
BoxDecoration
(
border:
new
Border
.
all
(
color:
const
Color
(
0xFFD9D9D9
),
),
),
child:
new
DropdownButton
<
int
>(
items:
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
].
map
((
int
value
)
{
return
new
DropdownMenuItem
<
int
>(
value:
value
,
child:
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
8.0
),
child:
new
Text
(
'Quantity
$value
'
,
style:
theme
.
quantityMenuStyle
),
),
);
}).
toList
(),
value:
quantity
,
onChanged:
quantityChanged
,
),
),
),
),
const
SizedBox
(
height:
16.0
),
new
SizedBox
(
height:
24.0
,
child:
new
Align
(
alignment:
FractionalOffset
.
bottomLeft
,
child:
new
Text
(
product
.
vendor
.
name
,
style:
theme
.
vendorTitleStyle
),
),
),
const
SizedBox
(
height:
16.0
),
new
Text
(
product
.
vendor
.
description
,
style:
theme
.
vendorStyle
),
const
SizedBox
(
height:
24.0
),
],
),
),
],
new
LayoutId
(
id:
_HeadingLayout
.
vendor
,
child:
new
_VendorItem
(
vendor:
product
.
vendor
),
),
],
),
),
),
);
...
...
@@ -130,9 +211,9 @@ class OrderPage extends StatefulWidget {
_OrderPageState
createState
()
=>
new
_OrderPageState
();
}
//
/ Displays a product's OrderItem
above photos of all of the other products
//
/
arranged in two columns. Enables the user to specify a quantity and add an
//
/
order to the shopping cart.
//
Displays a product's heading
above photos of all of the other products
// arranged in two columns. Enables the user to specify a quantity and add an
// order to the shopping cart.
class
_OrderPageState
extends
State
<
OrderPage
>
{
GlobalKey
<
ScaffoldState
>
scaffoldKey
;
...
...
@@ -185,24 +266,20 @@ class _OrderPageState extends State<OrderPage> {
),
body:
new
CustomScrollView
(
slivers:
<
Widget
>[
new
SliverList
(
delegate:
new
SliverChildListDelegate
(<
Widget
>[
new
OrderItem
(
product:
config
.
order
.
product
,
quantity:
currentOrder
.
quantity
,
quantityChanged:
(
int
value
)
{
updateOrder
(
quantity:
value
);
},
),
const
SizedBox
(
height:
24.0
),
]),
new
SliverToBoxAdapter
(
child:
new
_Heading
(
product:
config
.
order
.
product
,
quantity:
currentOrder
.
quantity
,
quantityChanged:
(
int
value
)
{
updateOrder
(
quantity:
value
);
},
),
),
new
SliverPadding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
padding:
const
EdgeInsets
.
fromLTRB
(
8.0
,
32.0
,
8.0
,
8.0
),
sliver:
new
SliverGrid
(
gridDelegate:
const
SliverGridDelegateWith
FixedCrossAxisCou
nt
(
crossAxisCount:
2
,
gridDelegate:
const
SliverGridDelegateWith
MaxCrossAxisExte
nt
(
maxCrossAxisExtent:
248.0
,
mainAxisSpacing:
8.0
,
crossAxisSpacing:
8.0
,
childAspectRatio:
160.0
/
216.0
,
// width/height
),
delegate:
new
SliverChildListDelegate
(
config
.
products
...
...
@@ -225,11 +302,11 @@ class _OrderPageState extends State<OrderPage> {
}
}
//
/
Displays a full-screen modal OrderPage.
//
/
//
/
The order field will be replaced each time the user reconfigures the order.
//
/
When the user backs out of this route the completer's value will be the
//
/
final value of the order field.
// Displays a full-screen modal OrderPage.
//
// The order field will be replaced each time the user reconfigures the order.
// When the user backs out of this route the completer's value will be the
// final value of the order field.
class
ShrineOrderRoute
extends
ShrinePageRoute
<
Order
>
{
ShrineOrderRoute
({
this
.
order
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment