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
309b9f80
Commit
309b9f80
authored
Jun 02, 2016
by
Hans Muller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Version 0.0 of a gallery demo of the Material Design "Shrine" app (#4327)
parent
a4640521
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1070 additions
and
13 deletions
+1070
-13
pubspec.yaml
dev/benchmarks/complex_layout/pubspec.yaml
+1
-1
flutter.yaml
examples/flutter_gallery/flutter.yaml
+4
-1
all.dart
examples/flutter_gallery/lib/demo/all.dart
+1
-0
shrine_data.dart
examples/flutter_gallery/lib/demo/shrine/shrine_data.dart
+264
-0
shrine_home.dart
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
+295
-0
shrine_order.dart
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
+227
-0
shrine_page.dart
examples/flutter_gallery/lib/demo/shrine/shrine_page.dart
+60
-0
shrine_theme.dart
examples/flutter_gallery/lib/demo/shrine/shrine_theme.dart
+47
-0
shrine_types.dart
examples/flutter_gallery/lib/demo/shrine/shrine_types.dart
+103
-0
shrine_demo.dart
examples/flutter_gallery/lib/demo/shrine_demo.dart
+46
-0
app.dart
examples/flutter_gallery/lib/gallery/app.dart
+1
-0
home.dart
examples/flutter_gallery/lib/gallery/home.dart
+1
-0
pubspec.yaml
examples/flutter_gallery/pubspec.yaml
+1
-1
app_bar.dart
packages/flutter/lib/src/material/app_bar.dart
+1
-1
card.dart
packages/flutter/lib/src/material/card.dart
+7
-3
navigator.dart
packages/flutter/lib/src/widgets/navigator.dart
+11
-6
No files found.
dev/benchmarks/complex_layout/pubspec.yaml
View file @
309b9f80
...
...
@@ -6,7 +6,7 @@ dependencies:
path
:
../../../packages/flutter
flutter_driver
:
path
:
../../../packages/flutter_driver
flutter_gallery_assets
:
'
0.0.1
6
'
flutter_gallery_assets
:
'
0.0.1
8
'
dev_dependencies
:
flutter_test
:
...
...
examples/flutter_gallery/flutter.yaml
View file @
309b9f80
...
...
@@ -37,5 +37,8 @@ assets:
-
packages/flutter_gallery_assets/landscape_9.jpg
-
packages/flutter_gallery_assets/landscape_10.jpg
-
packages/flutter_gallery_assets/landscape_11.jpg
-
packages/flutter_gallery_assets/shadow.png
-
lib/gallery/example_code.dart
fonts
:
-
family
:
AbrilFatface
fonts
:
-
asset
:
packages/flutter_gallery_assets/shrine/fonts/abrilfatface/AbrilFatface-Regular.ttf
examples/flutter_gallery/lib/demo/all.dart
View file @
309b9f80
...
...
@@ -25,6 +25,7 @@ export 'persistent_bottom_sheet_demo.dart';
export
'progress_indicator_demo.dart'
;
export
'scrollable_tabs_demo.dart'
;
export
'selection_controls_demo.dart'
;
export
'shrine_demo.dart'
;
export
'slider_demo.dart'
;
export
'snack_bar_demo.dart'
;
export
'tabs_demo.dart'
;
...
...
examples/flutter_gallery/lib/demo/shrine/shrine_data.dart
0 → 100644
View file @
309b9f80
This diff is collapsed.
Click to expand it.
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:collection'
show
HashSet
;
import
'package:flutter/material.dart'
;
import
'shrine_data.dart'
;
import
'shrine_order.dart'
;
import
'shrine_page.dart'
;
import
'shrine_theme.dart'
;
import
'shrine_types.dart'
;
const
double
unitSize
=
kToolBarHeight
;
Map
<
Product
,
Order
>
shoppingCart
=
<
Product
,
Order
>{};
/// Displays the Vendor's name and avatar.
class
VendorItem
extends
StatelessWidget
{
VendorItem
({
Key
key
,
this
.
vendor
})
:
super
(
key:
key
)
{
assert
(
vendor
!=
null
);
}
final
Vendor
vendor
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
SizedBox
(
height:
24.0
,
child:
new
Row
(
children:
<
Widget
>[
new
SizedBox
(
width:
24.0
,
child:
new
ClipRRect
(
xRadius:
12.0
,
yRadius:
12.0
,
child:
new
NetworkImage
(
fit:
ImageFit
.
cover
,
src:
vendor
.
avatarUrl
)
)
),
new
SizedBox
(
width:
8.0
),
new
Flexible
(
child:
new
Text
(
vendor
.
name
,
style:
ShrineTheme
.
of
(
context
).
vendorItemStyle
)
)
]
)
);
}
}
/// Displays the product's price. If the product is in the shopping cart the background
/// is highlighted.
class
PriceItem
extends
StatelessWidget
{
PriceItem
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
assert
(
product
!=
null
);
}
final
Product
product
;
@override
Widget
build
(
BuildContext
context
)
{
BoxDecoration
decoration
;
if
(
shoppingCart
[
product
]
!=
null
)
decoration
=
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFFFE0E0
));
return
new
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
,
vertical:
8.0
),
decoration:
decoration
,
child:
new
Text
(
product
.
priceString
,
style:
ShrineTheme
.
of
(
context
).
priceStyle
)
);
}
}
/// Layout the main left and right elements of a FeatureItem.
class
FeatureLayout
extends
MultiChildLayoutDelegate
{
FeatureLayout
();
static
final
String
left
=
'left'
;
static
final
String
right
=
'right'
;
// 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
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
));
}
@override
bool
shouldRelayout
(
FeatureLayout
oldDelegate
)
=>
false
;
}
/// A card that highlights the "featured" catalog item.
class
FeatureItem
extends
StatelessWidget
{
FeatureItem
({
Key
key
,
this
.
product
})
:
super
(
key:
key
)
{
assert
(
product
.
featureTitle
!=
null
);
assert
(
product
.
featureDescription
!=
null
);
}
final
Product
product
;
@override
Widget
build
(
BuildContext
context
)
{
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
AspectRatio
(
aspectRatio:
3.0
/
3.5
,
child:
new
Material
(
type:
MaterialType
.
card
,
elevation:
1
,
child:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
SizedBox
(
height:
unitSize
,
child:
new
Align
(
alignment:
FractionalOffset
.
topRight
,
child:
new
PriceItem
(
product:
product
)
)
),
new
Flexible
(
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
NetworkImage
(
fit:
ImageFit
.
cover
,
src:
product
.
imageUrl
)
)
)
),
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
)
]
)
)
)
]
)
)
]
)
)
);
}
}
/// 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
)
{
assert
(
product
!=
null
);
}
final
Product
product
;
final
VoidCallback
onPressed
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Card
(
child:
new
Padding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
child:
new
Column
(
children:
<
Widget
>[
new
Align
(
alignment:
FractionalOffset
.
centerRight
,
child:
new
PriceItem
(
product:
product
)
),
new
SizedBox
(
width:
144.0
,
height:
144.0
,
child:
new
Stack
(
children:
<
Widget
>[
new
Hero
(
tag:
productHeroTag
,
key:
new
ObjectKey
(
product
),
child:
new
NetworkImage
(
fit:
ImageFit
.
contain
,
src:
product
.
imageUrl
)
),
new
Material
(
color:
Theme
.
of
(
context
).
canvasColor
.
withAlpha
(
0x00
),
child:
new
InkWell
(
onTap:
onPressed
)
),
]
)
),
new
VendorItem
(
vendor:
product
.
vendor
)
]
)
)
);
}
}
/// The Shrine app's home page. Displays the featured item above all of the
/// product items arranged in two columns.
class
ShrineHome
extends
StatefulWidget
{
@override
_ShrineHomeState
createState
()
=>
new
_ShrineHomeState
();
}
class
_ShrineHomeState
extends
State
<
ShrineHome
>
{
final
List
<
Product
>
_products
=
allProducts
();
void
handleCompletedOrder
(
Order
completedOrder
)
{
assert
(
completedOrder
.
product
!=
null
);
if
(
completedOrder
.
inCart
&&
completedOrder
.
quantity
>
0
)
shoppingCart
[
completedOrder
.
product
]
=
completedOrder
;
else
shoppingCart
[
completedOrder
.
product
]
=
null
;
}
void
showOrderPage
(
Product
product
)
{
final
Order
order
=
shoppingCart
[
product
]
??
new
Order
(
product:
product
);
final
Completer
<
Order
>
completer
=
new
Completer
<
Order
>();
final
Key
productKey
=
new
ObjectKey
(
product
);
final
Set
<
Key
>
mostValuableKeys
=
new
HashSet
<
Key
>();
mostValuableKeys
.
add
(
productKey
);
Navigator
.
push
(
context
,
new
ShrineOrderRoute
(
order:
order
,
settings:
new
RouteSettings
(
mostValuableKeys:
mostValuableKeys
),
completer:
completer
,
builder:
(
BuildContext
context
)
{
return
new
OrderPage
(
order:
order
,
products:
_products
);
}
));
completer
.
future
.
then
(
handleCompletedOrder
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
Product
featured
=
_products
.
firstWhere
((
Product
product
)
=>
product
.
featureDescription
!=
null
);
return
new
ShrinePage
(
body:
new
ScrollableViewport
(
child:
new
Column
(
children:
<
Widget
>[
new
Container
(
margin:
new
EdgeInsets
.
only
(
bottom:
8.0
),
child:
new
FeatureItem
(
product:
featured
)
),
new
FixedColumnCountGrid
(
columnCount:
2
,
rowSpacing:
8.0
,
columnSpacing:
8.0
,
padding:
const
EdgeInsets
.
all
(
8.0
),
tileAspectRatio:
160.0
/
216.0
,
// width/height
children:
_products
.
map
((
Product
product
)
{
return
new
ProductItem
(
product:
product
,
onPressed:
()
{
showOrderPage
(
product
);
}
);
}).
toList
()
)
]
)
)
);
}
}
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter/material.dart'
;
import
'../shrine_demo.dart'
show
ShrinePageRoute
;
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
)
{
assert
(
product
!=
null
);
assert
(
quantity
!=
null
&&
quantity
>=
0
&&
quantity
<=
5
);
}
final
Product
product
;
final
int
quantity
;
final
ValueChanged
<
int
>
quantityChanged
;
@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
,
child:
new
Hero
(
tag:
productHeroTag
,
child:
new
NetworkImage
(
fit:
ImageFit
.
contain
,
src:
product
.
imageUrl
)
)
)
),
new
SizedBox
(
height:
24.0
),
new
Row
(
children:
<
Widget
>[
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
child:
new
Center
(
child:
new
Icon
(
icon:
Icons
.
info_outline
,
size:
24.0
,
color:
const
Color
(
0xFFFFE0E0
)
)
)
),
new
Flexible
(
child:
new
Text
(
product
.
name
,
style:
theme
.
featureTitleStyle
)
)
]
),
new
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
56.0
),
child:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
SizedBox
(
height:
24.0
),
new
Text
(
product
.
description
,
style:
theme
.
featureStyle
),
new
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
Text
(
'Quantity
$value
'
,
style:
theme
.
quantityMenuStyle
)
);
}).
toList
(),
value:
quantity
,
onChanged:
quantityChanged
)
)
)
),
new
SizedBox
(
height:
16.0
),
new
SizedBox
(
height:
24.0
,
child:
new
Align
(
alignment:
FractionalOffset
.
bottomLeft
,
child:
new
Text
(
product
.
vendor
.
name
,
style:
theme
.
vendorTitleStyle
)
)
),
new
SizedBox
(
height:
16.0
),
new
Text
(
product
.
vendor
.
description
,
style:
theme
.
vendorStyle
),
new
SizedBox
(
height:
24.0
)
]
)
)
]
)
)
);
}
}
class
OrderPage
extends
StatefulWidget
{
OrderPage
({
Key
key
,
this
.
order
,
this
.
products
})
:
super
(
key:
key
)
{
assert
(
order
!=
null
);
assert
(
products
!=
null
&&
products
.
length
>
0
);
}
final
Order
order
;
final
List
<
Product
>
products
;
@override
_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.
class
_OrderPageState
extends
State
<
OrderPage
>
{
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>(
debugLabel:
'Order Page'
);
Order
get
currentOrder
=>
ShrineOrderRoute
.
of
(
context
).
order
;
set
currentOrder
(
Order
value
)
{
ShrineOrderRoute
.
of
(
context
).
order
=
value
;
}
void
updateOrder
({
int
quantity
,
bool
inCart
})
{
Order
newOrder
=
currentOrder
.
copyWith
(
quantity:
quantity
,
inCart:
inCart
);
if
(
currentOrder
!=
newOrder
)
{
setState
(()
{
currentOrder
=
newOrder
;
});
}
}
void
showSnackBarMessage
(
String
message
)
{
scaffoldKey
.
currentState
.
showSnackBar
(
new
SnackBar
(
content:
new
Text
(
message
)));
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
ShrinePage
(
scaffoldKey:
scaffoldKey
,
floatingActionButton:
new
FloatingActionButton
(
onPressed:
()
{
updateOrder
(
inCart:
true
);
showSnackBarMessage
(
'There are
${currentOrder.quantity}
items in the shopping cart'
);
},
backgroundColor:
const
Color
(
0xFF16F0F0
),
child:
new
Icon
(
icon:
Icons
.
add_shopping_cart
,
color:
Colors
.
black
)
),
body:
new
Block
(
children:
<
Widget
>[
new
OrderItem
(
product:
config
.
order
.
product
,
quantity:
currentOrder
.
quantity
,
quantityChanged:
(
int
value
)
{
updateOrder
(
quantity:
value
);
}
),
new
SizedBox
(
height:
24.0
),
new
FixedColumnCountGrid
(
columnCount:
2
,
rowSpacing:
8.0
,
columnSpacing:
8.0
,
padding:
const
EdgeInsets
.
all
(
8.0
),
tileAspectRatio:
160.0
/
216.0
,
// width/height
children:
config
.
products
.
where
((
Product
product
)
=>
product
!=
config
.
order
.
product
)
.
map
((
Product
product
)
{
return
new
Card
(
elevation:
0
,
child:
new
NetworkImage
(
fit:
ImageFit
.
contain
,
src:
product
.
imageUrl
)
);
}).
toList
()
)
]
)
);
}
}
/// 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
,
WidgetBuilder
builder
,
Completer
<
Order
>
completer
,
RouteSettings
settings:
const
RouteSettings
()
})
:
super
(
builder:
builder
,
completer:
completer
,
settings:
settings
)
{
assert
(
order
!=
null
);
}
Order
order
;
@override
Order
get
currentResult
=>
order
;
static
ShrineOrderRoute
of
(
BuildContext
context
)
=>
ModalRoute
.
of
(
context
);
}
examples/flutter_gallery/lib/demo/shrine/shrine_page.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'shrine_theme.dart'
;
enum
ShrineAction
{
sortByPrice
,
sortByProduct
,
emptyCart
}
/// Defines the Scaffold, AppBar, etc that the demo pages have in common.
class
ShrinePage
extends
StatelessWidget
{
ShrinePage
({
Key
key
,
this
.
scaffoldKey
,
this
.
body
,
this
.
floatingActionButton
})
:
super
(
key:
key
);
final
Key
scaffoldKey
;
final
Widget
body
;
final
Widget
floatingActionButton
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
scaffoldKey
,
appBar:
new
AppBar
(
title:
new
Center
(
child:
new
Text
(
'SHRINE'
,
style:
ShrineTheme
.
of
(
context
).
appBarTitleStyle
)
),
backgroundColor:
Theme
.
of
(
context
).
canvasColor
,
actions:
<
Widget
>[
// TODO(hansmuller): implement the actions.
new
IconButton
(
icon:
Icons
.
shopping_cart
,
tooltip:
'Shopping cart'
,
onPressed:
()
{
/* activate the button for now */
}
),
new
PopupMenuButton
<
ShrineAction
>(
itemBuilder:
(
BuildContext
context
)
=>
<
PopupMenuItem
<
ShrineAction
>>[
new
PopupMenuItem
<
ShrineAction
>(
value:
ShrineAction
.
sortByPrice
,
child:
new
Text
(
'Sort by price'
)
),
new
PopupMenuItem
<
ShrineAction
>(
value:
ShrineAction
.
sortByProduct
,
child:
new
Text
(
'Sort by product'
)
),
new
PopupMenuItem
<
ShrineAction
>(
value:
ShrineAction
.
emptyCart
,
child:
new
Text
(
'Empty shopping cart'
)
)
]
)
]
),
floatingActionButton:
floatingActionButton
,
body:
body
);
}
}
examples/flutter_gallery/lib/demo/shrine/shrine_theme.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
class
ShrineStyle
extends
TextStyle
{
const
ShrineStyle
.
roboto
(
double
size
,
FontWeight
weight
,
Color
color
)
:
super
(
inherit:
false
,
color:
color
,
fontSize:
size
,
fontWeight:
weight
,
textBaseline:
TextBaseline
.
alphabetic
);
const
ShrineStyle
.
abrilFatface
(
double
size
,
FontWeight
weight
,
Color
color
)
:
super
(
inherit:
false
,
color:
color
,
fontFamily:
'AbrilFatface'
,
fontSize:
size
,
fontWeight:
weight
,
textBaseline:
TextBaseline
.
alphabetic
);
}
TextStyle
robotoRegular12
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
12.0
,
FontWeight
.
w500
,
color
);
TextStyle
robotoLight12
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
12.0
,
FontWeight
.
w300
,
color
);
TextStyle
robotoRegular14
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
14.0
,
FontWeight
.
w500
,
color
);
TextStyle
robotoMedium14
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
14.0
,
FontWeight
.
w600
,
color
);
TextStyle
robotoLight14
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
14.0
,
FontWeight
.
w300
,
color
);
TextStyle
robotoRegular20
(
Color
color
)
=>
new
ShrineStyle
.
roboto
(
20.0
,
FontWeight
.
w500
,
color
);
TextStyle
abrilFatfaceRegular24
(
Color
color
)
=>
new
ShrineStyle
.
abrilFatface
(
24.0
,
FontWeight
.
w500
,
color
);
TextStyle
abrilFatfaceRegular34
(
Color
color
)
=>
new
ShrineStyle
.
abrilFatface
(
34.0
,
FontWeight
.
w500
,
color
);
/// The TextStyles and Colors used for titles, labels, and descriptions. This
/// InheritedWidget is shared by all of the routes and widgets created for
/// the Shrine app.
class
ShrineTheme
extends
InheritedWidget
{
ShrineTheme
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
child
!=
null
);
}
final
TextStyle
appBarTitleStyle
=
robotoRegular20
(
Colors
.
black87
);
final
TextStyle
vendorItemStyle
=
robotoRegular12
(
const
Color
(
0xFF81959D
));
final
TextStyle
priceStyle
=
robotoRegular14
(
Colors
.
black87
);
final
TextStyle
featureTitleStyle
=
abrilFatfaceRegular34
(
Colors
.
black87
);
final
TextStyle
featureStyle
=
robotoLight14
(
Colors
.
black54
);
final
TextStyle
orderTitleStyle
=
abrilFatfaceRegular24
(
Colors
.
black87
);
final
TextStyle
orderStyle
=
robotoLight14
(
Colors
.
black54
);
final
TextStyle
vendorTitleStyle
=
robotoMedium14
(
Colors
.
black87
);
final
TextStyle
vendorStyle
=
robotoLight14
(
Colors
.
black54
);
final
TextStyle
quantityMenuStyle
=
robotoLight14
(
Colors
.
black54
);
static
ShrineTheme
of
(
BuildContext
context
)
=>
context
.
inheritFromWidgetOfExactType
(
ShrineTheme
);
@override
bool
updateShouldNotify
(
ShrineTheme
old
)
=>
false
;
}
examples/flutter_gallery/lib/demo/shrine/shrine_types.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
show
hashValues
;
const
String
productHeroTag
=
'Product'
;
class
Vendor
{
const
Vendor
({
this
.
name
,
this
.
description
,
this
.
avatarUrl
});
final
String
name
;
final
String
description
;
final
String
avatarUrl
;
bool
isValid
()
{
return
name
!=
null
&&
description
!=
null
&&
avatarUrl
!=
null
;
}
@override
String
toString
()
=>
'Vendor(
$name
)'
;
}
class
Product
{
const
Product
({
this
.
name
,
this
.
description
,
this
.
featureTitle
,
this
.
featureDescription
,
this
.
imageUrl
,
this
.
categories
,
this
.
price
,
this
.
vendor
});
final
String
name
;
final
String
description
;
final
String
featureTitle
;
final
String
featureDescription
;
final
String
imageUrl
;
final
List
<
String
>
categories
;
final
double
price
;
final
Vendor
vendor
;
String
get
priceString
=>
'
\$
${price.floor()}
'
;
bool
isValid
()
{
return
name
!=
null
&&
description
!=
null
&&
imageUrl
!=
null
&&
categories
!=
null
&&
categories
.
length
>
0
&&
price
!=
null
&&
vendor
.
isValid
();
}
@override
String
toString
()
=>
'Product(
$name
)'
;
}
class
Order
{
Order
({
this
.
product
,
this
.
quantity
:
1
,
this
.
inCart
:
false
})
{
assert
(
product
!=
null
);
assert
(
quantity
!=
null
&&
quantity
>=
0
);
assert
(
inCart
!=
null
);
}
final
Product
product
;
final
int
quantity
;
final
bool
inCart
;
Order
copyWith
({
Product
product
,
int
quantity
,
bool
inCart
})
{
return
new
Order
(
product:
product
??
this
.
product
,
quantity:
quantity
??
this
.
quantity
,
inCart:
inCart
??
this
.
inCart
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
Order
typedOther
=
other
;
return
product
==
typedOther
.
product
&&
quantity
==
typedOther
.
quantity
&&
inCart
==
typedOther
.
inCart
;
}
@override
int
get
hashCode
=>
hashValues
(
product
,
quantity
,
inCart
);
@override
String
toString
()
=>
'Order(
$product
, quantity=
$quantity
, inCart=
$inCart
)'
;
}
examples/flutter_gallery/lib/demo/shrine_demo.dart
0 → 100644
View file @
309b9f80
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter/material.dart'
;
import
'shrine/shrine_home.dart'
show
ShrineHome
;
import
'shrine/shrine_theme.dart'
show
ShrineTheme
;
// This code would ordinarily be part of the MaterialApp's home. It's being
// used by the ShrineDemo and by each route pushed from there because this
// isn't a standalone app with its own main() and MaterialApp.
Widget
buildShrine
(
Widget
child
)
{
return
new
Theme
(
data:
new
ThemeData
(
primarySwatch:
Colors
.
grey
),
child:
new
IconTheme
(
data:
new
IconThemeData
(
color:
const
Color
(
0xFF707070
)),
child:
new
ShrineTheme
(
child:
child
)
)
);
}
// In a standalone version of this app, MaterialPageRoute<T> could be used directly.
class
ShrinePageRoute
<
T
>
extends
MaterialPageRoute
<
T
>
{
ShrinePageRoute
({
WidgetBuilder
builder
,
Completer
<
T
>
completer
,
RouteSettings
settings:
const
RouteSettings
()
})
:
super
(
builder:
builder
,
completer:
completer
,
settings:
settings
);
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
)
{
return
buildShrine
(
super
.
buildPage
(
context
,
animation
,
forwardAnimation
));
}
}
class
ShrineDemo
extends
StatelessWidget
{
static
const
String
routeName
=
'/shrine'
;
// Used by the Gallery app.
@override
Widget
build
(
BuildContext
context
)
=>
buildShrine
(
new
ShrineHome
());
}
examples/flutter_gallery/lib/gallery/app.dart
View file @
309b9f80
...
...
@@ -9,6 +9,7 @@ import '../demo/all.dart';
import
'home.dart'
;
final
Map
<
String
,
WidgetBuilder
>
kRoutes
=
<
String
,
WidgetBuilder
>{
ShrineDemo
.
routeName
:
(
BuildContext
context
)
=>
new
ShrineDemo
(),
WeatherDemo
.
routeName
:
(
BuildContext
context
)
=>
new
WeatherDemo
(),
FitnessDemo
.
routeName
:
(
BuildContext
context
)
=>
new
FitnessDemo
(),
Calculator
.
routeName
:
(
BuildContext
context
)
=>
new
Calculator
(),
...
...
examples/flutter_gallery/lib/gallery/home.dart
View file @
309b9f80
...
...
@@ -71,6 +71,7 @@ class GalleryHomeState extends State<GalleryHome> {
leading:
new
Icon
(
icon:
Icons
.
star
),
title:
new
Text
(
'Demos'
),
children:
<
Widget
>[
new
GalleryItem
(
title:
'Shrine'
,
routeName:
ShrineDemo
.
routeName
),
new
GalleryItem
(
title:
'Weather'
,
routeName:
WeatherDemo
.
routeName
),
new
GalleryItem
(
title:
'Fitness'
,
routeName:
FitnessDemo
.
routeName
),
new
GalleryItem
(
title:
'Calculator'
,
routeName:
Calculator
.
routeName
),
...
...
examples/flutter_gallery/pubspec.yaml
View file @
309b9f80
...
...
@@ -10,7 +10,7 @@ dependencies:
path
:
../../packages/flutter_sprites
flutter_markdown
:
path
:
../../packages/flutter_markdown
flutter_gallery_assets
:
'
0.0.1
6
'
flutter_gallery_assets
:
'
0.0.1
8
'
dev_dependencies
:
test
:
any
# flutter_test provides the version constraints
...
...
packages/flutter/lib/src/material/app_bar.dart
View file @
309b9f80
...
...
@@ -183,7 +183,7 @@ class AppBar extends StatelessWidget {
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
final
ThemeData
theme
=
Theme
.
of
(
context
);
IconThemeData
iconTheme
=
theme
.
primaryIconTheme
;
IconThemeData
iconTheme
=
IconTheme
.
of
(
context
)
??
theme
.
primaryIconTheme
;
TextStyle
centerStyle
=
textTheme
?.
title
??
theme
.
primaryTextTheme
.
title
;
TextStyle
sideStyle
=
textTheme
?.
body1
??
theme
.
primaryTextTheme
.
body1
;
...
...
packages/flutter/lib/src/material/card.dart
View file @
309b9f80
...
...
@@ -17,8 +17,9 @@ class Card extends StatelessWidget {
/// Creates a material design card.
const
Card
({
Key
key
,
this
.
child
,
this
.
color
this
.
color
,
this
.
elevation
:
2
,
this
.
child
})
:
super
(
key:
key
);
/// The widget below this widget in the tree.
...
...
@@ -27,6 +28,9 @@ class Card extends StatelessWidget {
/// The color of material used for this card.
final
Color
color
;
/// The following elevations have defined shadows: 1, 2, 3, 4, 6, 8, 9, 12, 16, 24
final
int
elevation
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Container
(
...
...
@@ -34,7 +38,7 @@ class Card extends StatelessWidget {
child:
new
Material
(
color:
color
,
type:
MaterialType
.
card
,
elevation:
2
,
elevation:
elevation
,
child:
child
)
);
...
...
packages/flutter/lib/src/widgets/navigator.dart
View file @
309b9f80
...
...
@@ -32,6 +32,10 @@ abstract class Route<T> {
/// Called after install() when the route is pushed onto the navigator.
void
didPush
()
{
}
/// When this route is popped (see [Navigator.pop]) if the result isn't
/// specified or if it's null, this value will be used instead.
T
get
currentResult
=>
null
;
/// Called after install() when the route replaced another in the navigator.
void
didReplace
(
Route
<
dynamic
>
oldRoute
)
{
}
...
...
@@ -427,7 +431,7 @@ class NavigatorState extends State<Navigator> {
assert
(
route
.
_navigator
==
this
);
bool
debugPredictedWouldPop
;
assert
(()
{
debugPredictedWouldPop
=
!
route
.
willHandlePopInternally
;
return
true
;
});
if
(
route
.
didPop
(
result
))
{
if
(
route
.
didPop
(
result
??
route
.
currentResult
))
{
assert
(
debugPredictedWouldPop
);
if
(
_history
.
length
>
1
)
{
setState
(()
{
...
...
@@ -564,11 +568,12 @@ class NavigatorTransaction {
/// (if any) is notified using its didPop() method, and the previous route is
/// notified using [Route.didChangeNext].
///
/// If non-null, [result] will be used as the result of the route. Routes
/// such as dialogs or popup menus typically use this mechanism to return the
/// value selected by the user to the widget that created their route. The
/// type of [result], if provided, must match the type argument of the class
/// of the current route. (In practice, this is usually "dynamic".)
/// If non-null, [result] will be used as the result of the route, otherwise
/// the route's [Route.currentValue] will be used. Routes such as dialogs or
/// popup menus typically use this mechanism to return the value selected by
/// the user to the widget that created their route. The type of [result],
/// if provided, must match the type argument of the class of the current
/// route. (In practice, this is usually "dynamic".)
///
/// Returns true if a route was popped; returns false if there are no further
/// previous routes.
...
...
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