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
6f0635d6
Commit
6f0635d6
authored
Jul 21, 2016
by
Dragoș Tiselice
Committed by
GitHub
Jul 21, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4953 from flutter/drawer-header-update
Updated DrawerHeader to new spec.
parents
3aa26cb1
65e77142
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
296 additions
and
33 deletions
+296
-33
card_collection.dart
dev/manual_tests/card_collection.dart
+1
-1
pageable_list.dart
dev/manual_tests/pageable_list.dart
+1
-1
pesto_demo.dart
examples/flutter_gallery/lib/demo/pesto_demo.dart
+3
-2
drawer.dart
examples/flutter_gallery/lib/gallery/drawer.dart
+1
-1
stock_home.dart
examples/stocks/lib/stock_home.dart
+1
-1
material.dart
packages/flutter/lib/material.dart
+1
-0
drawer_header.dart
packages/flutter/lib/src/material/drawer_header.dart
+29
-26
user_accounts_drawer_header.dart
...flutter/lib/src/material/user_accounts_drawer_header.dart
+166
-0
drawer_test.dart
packages/flutter/test/material/drawer_test.dart
+19
-1
user_accounts_drawer_header_test.dart
...utter/test/material/user_accounts_drawer_header_test.dart
+74
-0
No files found.
dev/manual_tests/card_collection.dart
View file @
6f0635d6
...
@@ -126,7 +126,7 @@ class CardCollectionState extends State<CardCollection> {
...
@@ -126,7 +126,7 @@ class CardCollectionState extends State<CardCollection> {
child:
new
IconTheme
(
child:
new
IconTheme
(
data:
const
IconThemeData
(
color:
Colors
.
black
),
data:
const
IconThemeData
(
color:
Colors
.
black
),
child:
new
Block
(
children:
<
Widget
>[
child:
new
Block
(
children:
<
Widget
>[
new
DrawerHeader
(
c
ontent
:
new
Center
(
child:
new
Text
(
'Options'
))),
new
DrawerHeader
(
c
hild
:
new
Center
(
child:
new
Text
(
'Options'
))),
buildDrawerCheckbox
(
"Make card labels editable"
,
_editable
,
_toggleEditable
),
buildDrawerCheckbox
(
"Make card labels editable"
,
_editable
,
_toggleEditable
),
buildDrawerCheckbox
(
"Snap fling scrolls to center"
,
_snapToCenter
,
_toggleSnapToCenter
),
buildDrawerCheckbox
(
"Snap fling scrolls to center"
,
_snapToCenter
,
_toggleSnapToCenter
),
buildDrawerCheckbox
(
"Fixed size cards"
,
_fixedSizeCards
,
_toggleFixedSizeCards
),
buildDrawerCheckbox
(
"Fixed size cards"
,
_fixedSizeCards
,
_toggleFixedSizeCards
),
...
...
dev/manual_tests/pageable_list.dart
View file @
6f0635d6
...
@@ -85,7 +85,7 @@ class PageableListAppState extends State<PageableListApp> {
...
@@ -85,7 +85,7 @@ class PageableListAppState extends State<PageableListApp> {
Widget
_buildDrawer
()
{
Widget
_buildDrawer
()
{
return
new
Drawer
(
return
new
Drawer
(
child:
new
Block
(
children:
<
Widget
>[
child:
new
Block
(
children:
<
Widget
>[
new
DrawerHeader
(
c
ontent
:
new
Center
(
child:
new
Text
(
'Options'
))),
new
DrawerHeader
(
c
hild
:
new
Center
(
child:
new
Text
(
'Options'
))),
new
DrawerItem
(
new
DrawerItem
(
icon:
new
Icon
(
Icons
.
more_horiz
),
icon:
new
Icon
(
Icons
.
more_horiz
),
selected:
scrollDirection
==
Axis
.
horizontal
,
selected:
scrollDirection
==
Axis
.
horizontal
,
...
...
examples/flutter_gallery/lib/demo/pesto_demo.dart
View file @
6f0635d6
...
@@ -121,7 +121,8 @@ class _PestoDemoState extends State<PestoDemo> {
...
@@ -121,7 +121,8 @@ class _PestoDemoState extends State<PestoDemo> {
child:
new
Block
(
child:
new
Block
(
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerHeader
(
new
DrawerHeader
(
content:
new
Column
(
child:
new
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
children:
<
Widget
>[
new
Container
(
new
Container
(
decoration:
new
BoxDecoration
(
decoration:
new
BoxDecoration
(
...
@@ -131,7 +132,7 @@ class _PestoDemoState extends State<PestoDemo> {
...
@@ -131,7 +132,7 @@ class _PestoDemoState extends State<PestoDemo> {
width:
72.0
,
width:
72.0
,
height:
72.0
,
height:
72.0
,
padding:
const
EdgeInsets
.
all
(
2.0
),
padding:
const
EdgeInsets
.
all
(
2.0
),
margin:
const
EdgeInsets
.
only
(
bottom:
8
.0
),
margin:
const
EdgeInsets
.
only
(
bottom:
16
.0
),
child:
new
ClipOval
(
child:
new
ClipOval
(
child:
new
Image
(
child:
new
Image
(
image:
new
AssetImage
(
_kUserImage
),
image:
new
AssetImage
(
_kUserImage
),
...
...
examples/flutter_gallery/lib/gallery/drawer.dart
View file @
6f0635d6
...
@@ -49,7 +49,7 @@ class GalleryDrawer extends StatelessWidget {
...
@@ -49,7 +49,7 @@ class GalleryDrawer extends StatelessWidget {
child:
new
Block
(
child:
new
Block
(
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerHeader
(
new
DrawerHeader
(
c
ontent
:
new
Center
(
child:
new
Text
(
'Flutter gallery'
))
c
hild
:
new
Center
(
child:
new
Text
(
'Flutter gallery'
))
),
),
new
DrawerItem
(
new
DrawerItem
(
icon:
new
Icon
(
Icons
.
brightness_5
),
icon:
new
Icon
(
Icons
.
brightness_5
),
...
...
examples/stocks/lib/stock_home.dart
View file @
6f0635d6
...
@@ -124,7 +124,7 @@ class StockHomeState extends State<StockHome> {
...
@@ -124,7 +124,7 @@ class StockHomeState extends State<StockHome> {
Widget
_buildDrawer
(
BuildContext
context
)
{
Widget
_buildDrawer
(
BuildContext
context
)
{
return
new
Drawer
(
return
new
Drawer
(
child:
new
Block
(
children:
<
Widget
>[
child:
new
Block
(
children:
<
Widget
>[
new
DrawerHeader
(
c
ontent
:
new
Center
(
child:
new
Text
(
'Stocks'
))),
new
DrawerHeader
(
c
hild
:
new
Center
(
child:
new
Text
(
'Stocks'
))),
new
DrawerItem
(
new
DrawerItem
(
icon:
new
Icon
(
Icons
.
assessment
),
icon:
new
Icon
(
Icons
.
assessment
),
selected:
true
,
selected:
true
,
...
...
packages/flutter/lib/material.dart
View file @
6f0635d6
...
@@ -73,5 +73,6 @@ export 'src/material/toggleable.dart';
...
@@ -73,5 +73,6 @@ export 'src/material/toggleable.dart';
export
'src/material/tooltip.dart'
;
export
'src/material/tooltip.dart'
;
export
'src/material/two_level_list.dart'
;
export
'src/material/two_level_list.dart'
;
export
'src/material/typography.dart'
;
export
'src/material/typography.dart'
;
export
'src/material/user_accounts_drawer_header.dart'
;
export
'widgets.dart'
;
export
'widgets.dart'
;
packages/flutter/lib/src/material/drawer_header.dart
View file @
6f0635d6
...
@@ -7,11 +7,11 @@ import 'package:flutter/widgets.dart';
...
@@ -7,11 +7,11 @@ import 'package:flutter/widgets.dart';
import
'debug.dart'
;
import
'debug.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
const
double
_kDrawerHeaderHeight
=
1
40.0
;
const
double
_kDrawerHeaderHeight
=
1
60.0
+
1.0
;
// bottom edge
/// The top-most region of a material design drawer. The header's [
backgroun
d]
/// The top-most region of a material design drawer. The header's [
chil
d]
/// widget
extends behind the system status bar and its [content] widget i
s
/// widget
is placed inside of a [Container] whose [decoration] can be passed a
s
///
stacked on top of the background and below the status bar
.
///
an argument
.
///
///
/// Part of the material design [Drawer].
/// Part of the material design [Drawer].
///
///
...
@@ -22,19 +22,24 @@ const double _kDrawerHeaderHeight = 140.0;
...
@@ -22,19 +22,24 @@ const double _kDrawerHeaderHeight = 140.0;
/// * [Drawer]
/// * [Drawer]
/// * [DrawerItem]
/// * [DrawerItem]
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
class
DrawerHeader
extends
StatelessWidget
{
class
DrawerHeader
extends
StatelessWidget
{
/// Creates a material design drawer header.
/// Creates a material design drawer header.
///
///
/// Requires one of its ancestors to be a [Material] widget.
/// Requires one of its ancestors to be a [Material] widget.
const
DrawerHeader
({
Key
key
,
this
.
background
,
this
.
content
})
:
super
(
key:
key
);
const
DrawerHeader
({
Key
key
,
this
.
decoration
,
this
.
child
})
:
super
(
key:
key
);
///
A widget that extends behind the system status bar and is stacked
///
Decoration for the main drawer header [Container]; useful for applying
/// b
ehind the [content] widget
.
/// b
ackgrounds
.
final
Widget
background
;
final
BoxDecoration
decoration
;
/// A widget that
's positioned below the status bar and stacked on top of the
/// A widget that
extends behind the system status bar and is placed inside a
/// [
background] widget. Typically a view of the user's id
.
/// [
Container]
.
final
Widget
c
ontent
;
final
Widget
c
hild
;
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
...
@@ -42,7 +47,7 @@ class DrawerHeader extends StatelessWidget {
...
@@ -42,7 +47,7 @@ class DrawerHeader extends StatelessWidget {
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
return
new
Container
(
return
new
Container
(
height:
statusBarHeight
+
_kDrawerHeaderHeight
,
height:
statusBarHeight
+
_kDrawerHeaderHeight
,
margin:
const
EdgeInsets
.
only
(
bottom:
7.0
),
// 8 less 1 for the bottom border.
margin:
const
EdgeInsets
.
only
(
bottom:
8.0
),
decoration:
new
BoxDecoration
(
decoration:
new
BoxDecoration
(
border:
const
Border
(
border:
const
Border
(
bottom:
const
BorderSide
(
bottom:
const
BorderSide
(
...
@@ -51,20 +56,18 @@ class DrawerHeader extends StatelessWidget {
...
@@ -51,20 +56,18 @@ class DrawerHeader extends StatelessWidget {
)
)
)
)
),
),
child:
new
Stack
(
child:
new
Container
(
children:
<
Widget
>[
padding:
new
EdgeInsets
.
only
(
background
??
new
Container
(),
top:
16.0
+
statusBarHeight
,
new
Positioned
(
left:
16.0
,
top:
statusBarHeight
+
16.0
,
right:
16.0
,
left:
16.0
,
bottom:
8.0
right:
16.0
,
),
bottom:
8.0
,
decoration:
decoration
,
child:
new
DefaultTextStyle
(
child:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
textTheme
.
body2
,
style:
Theme
.
of
(
context
).
textTheme
.
body2
,
child:
content
child:
child
)
)
)
]
)
)
);
);
}
}
...
...
packages/flutter/lib/src/material/user_accounts_drawer_header.dart
0 → 100644
View file @
6f0635d6
// Copyright 2015 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
'package:flutter/widgets.dart'
;
import
'debug.dart'
;
/// A material design [Drawer] header that identifies the app's user.
///
/// The top-most region of a material design drawer with user accounts. The
/// header's [decoration] is used to provide a background.
/// [currentAccountPicture] is the main account picture on the left, while
/// [otherAccountsPictures] are the smaller account pictures on the right.
/// [accountName] and [accountEmail] provide access to the top and bottom rows
/// of the account details in the lower part of the header. When touched, this
/// area triggers [onDetailsPressed] and toggles the dropdown icon on the right.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
///
/// * [Drawer]
/// * [DrawerItem]
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
class
UserAccountsDrawerHeader
extends
StatefulWidget
{
/// Creates a material design drawer header.
///
/// Requires one of its ancestors to be a [Material] widget.
UserAccountsDrawerHeader
({
Key
key
,
this
.
decoration
,
this
.
currentAccountPicture
,
this
.
otherAccountsPictures
,
this
.
accountName
,
this
.
accountEmail
,
this
.
onDetailsPressed
})
:
super
(
key:
key
);
/// A callback that gets called when the account name/email/dropdown
/// section is pressed.
final
VoidCallback
onDetailsPressed
;
/// Decoration for the main drawer header container useful for applying
/// backgrounds.
final
BoxDecoration
decoration
;
/// A widget placed in the upper-left corner representing the current
/// account picture. Normally a [CircleAvatar].
final
Widget
currentAccountPicture
;
/// A list of widgets that represent the user's accounts. Up to three of them
/// are arranged in a row in the header's upper-right corner. Normally a list
/// of [CircleAvatar] widgets.
final
List
<
Widget
>
otherAccountsPictures
;
/// A widget placed on the top row of the account details representing
/// account name.
final
Widget
accountName
;
/// A widget placed on the bottom row of the account details representing
/// account email.
final
Widget
accountEmail
;
@override
_UserAccountsDrawerHeaderState
createState
()
=>
new
_UserAccountsDrawerHeaderState
();
}
class
_UserAccountsDrawerHeaderState
extends
State
<
UserAccountsDrawerHeader
>
{
/// Saves whether the account dropdown is open or not.
bool
isOpen
=
false
;
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
final
List
<
Widget
>
otherAccountsPictures
=
config
.
otherAccountsPictures
??
<
Widget
>[];
return
new
DrawerHeader
(
decoration:
config
.
decoration
,
child:
new
Column
(
children:
<
Widget
>[
new
Flexible
(
child:
new
Stack
(
children:
<
Widget
>[
new
Positioned
(
top:
0.0
,
right:
0.0
,
child:
new
Row
(
children:
otherAccountsPictures
.
take
(
3
).
map
(
(
Widget
picture
)
{
return
new
Container
(
margin:
const
EdgeInsets
.
only
(
left:
16.0
),
width:
40.0
,
height:
40.0
,
child:
picture
);
}
).
toList
()
)
),
new
Positioned
(
top:
0.0
,
child:
new
Container
(
width:
72.0
,
height:
72.0
,
child:
config
.
currentAccountPicture
)
)
]
)
),
new
Container
(
height:
56.0
,
child:
new
InkWell
(
onTap:
()
{
setState
(()
{
isOpen
=
!
isOpen
;
});
if
(
config
.
onDetailsPressed
!=
null
)
config
.
onDetailsPressed
();
},
child:
new
Container
(
margin:
const
EdgeInsets
.
symmetric
(
vertical:
8.0
),
child:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
<
Widget
>[
new
DefaultTextStyle
(
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w500
,
color:
Colors
.
white
),
child:
config
.
accountName
),
new
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
<
Widget
>[
new
DefaultTextStyle
(
style:
const
TextStyle
(
color:
Colors
.
white
),
child:
config
.
accountEmail
),
new
Flexible
(
child:
new
Align
(
alignment:
FractionalOffset
.
centerRight
,
child:
new
Icon
(
isOpen
?
Icons
.
arrow_drop_up
:
Icons
.
arrow_drop_down
,
color:
Colors
.
white
)
)
)
]
)
]
)
)
)
)
]
)
);
}
}
packages/flutter/test/material/drawer_test.dart
View file @
6f0635d6
...
@@ -7,13 +7,18 @@ import 'package:flutter_test/flutter_test.dart';
...
@@ -7,13 +7,18 @@ import 'package:flutter_test/flutter_test.dart';
void
main
(
)
{
void
main
(
)
{
testWidgets
(
'Drawer control test'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Drawer control test'
,
(
WidgetTester
tester
)
async
{
final
Key
containerKey
=
new
Key
(
'container'
);
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
new
Scaffold
(
new
Scaffold
(
drawer:
new
Drawer
(
drawer:
new
Drawer
(
child:
new
Block
(
child:
new
Block
(
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerHeader
(
new
DrawerHeader
(
content:
new
Text
(
'header'
)
child:
new
Container
(
key:
containerKey
,
child:
new
Text
(
'header'
)
)
),
),
new
DrawerItem
(
new
DrawerItem
(
icon:
new
Icon
(
Icons
.
archive
),
icon:
new
Icon
(
Icons
.
archive
),
...
@@ -28,8 +33,21 @@ void main() {
...
@@ -28,8 +33,21 @@ void main() {
expect
(
find
.
text
(
'Archive'
),
findsNothing
);
expect
(
find
.
text
(
'Archive'
),
findsNothing
);
ScaffoldState
state
=
tester
.
firstState
(
find
.
byType
(
Scaffold
));
ScaffoldState
state
=
tester
.
firstState
(
find
.
byType
(
Scaffold
));
state
.
openDrawer
();
state
.
openDrawer
();
await
tester
.
pump
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
find
.
text
(
'Archive'
),
findsOneWidget
);
expect
(
find
.
text
(
'Archive'
),
findsOneWidget
);
RenderBox
box
=
tester
.
renderObject
(
find
.
byType
(
DrawerHeader
));
expect
(
box
.
size
.
height
,
equals
(
160.0
+
8.0
+
1.0
));
// height + bottom margin + bottom edge
final
double
drawerWidth
=
box
.
size
.
width
;
final
double
drawerHeight
=
box
.
size
.
height
;
box
=
tester
.
renderObject
(
find
.
byKey
(
containerKey
));
expect
(
box
.
size
.
width
,
equals
(
drawerWidth
-
2
*
16.0
));
expect
(
box
.
size
.
height
,
equals
(
drawerHeight
-
2
*
16.0
-
1.0
));
// bottom edge
expect
(
find
.
text
(
'header'
),
findsOneWidget
);
});
});
}
}
packages/flutter/test/material/user_accounts_drawer_header_test.dart
0 → 100644
View file @
6f0635d6
// 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
'package:flutter/rendering.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'UserAccuntsDrawerHeader test'
,
(
WidgetTester
tester
)
async
{
final
Key
avatarA
=
new
Key
(
'A'
);
final
Key
avatarC
=
new
Key
(
'C'
);
final
Key
avatarD
=
new
Key
(
'D'
);
await
tester
.
pumpWidget
(
new
Material
(
child:
new
UserAccountsDrawerHeader
(
currentAccountPicture:
new
CircleAvatar
(
key:
avatarA
,
child:
new
Text
(
'A'
)
),
otherAccountsPictures:
<
Widget
>[
new
CircleAvatar
(
child:
new
Text
(
'B'
)
),
new
CircleAvatar
(
key:
avatarC
,
child:
new
Text
(
'C'
)
),
new
CircleAvatar
(
key:
avatarD
,
child:
new
Text
(
'D'
)
),
new
CircleAvatar
(
child:
new
Text
(
'E'
)
)
],
accountName:
new
Text
(
"name"
),
accountEmail:
new
Text
(
"email"
)
)
)
);
expect
(
find
.
text
(
'A'
),
findsOneWidget
);
expect
(
find
.
text
(
'B'
),
findsOneWidget
);
expect
(
find
.
text
(
'C'
),
findsOneWidget
);
expect
(
find
.
text
(
'D'
),
findsOneWidget
);
expect
(
find
.
text
(
'E'
),
findsNothing
);
expect
(
find
.
text
(
'name'
),
findsOneWidget
);
expect
(
find
.
text
(
'email'
),
findsOneWidget
);
RenderBox
box
=
tester
.
renderObject
(
find
.
byKey
(
avatarA
));
expect
(
box
.
size
.
width
,
equals
(
72.0
));
expect
(
box
.
size
.
height
,
equals
(
72.0
));
box
=
tester
.
renderObject
(
find
.
byKey
(
avatarC
));
expect
(
box
.
size
.
width
,
equals
(
40.0
));
expect
(
box
.
size
.
height
,
equals
(
40.0
));
Point
topLeft
=
tester
.
getTopLeft
(
find
.
byType
(
UserAccountsDrawerHeader
));
Point
topRight
=
tester
.
getTopRight
(
find
.
byType
(
UserAccountsDrawerHeader
));
Point
avatarATopLeft
=
tester
.
getTopLeft
(
find
.
byKey
(
avatarA
));
Point
avatarDTopRight
=
tester
.
getTopRight
(
find
.
byKey
(
avatarD
));
Point
avatarCTopRight
=
tester
.
getTopRight
(
find
.
byKey
(
avatarC
));
expect
(
avatarATopLeft
.
x
-
topLeft
.
x
,
equals
(
16.0
));
expect
(
avatarATopLeft
.
y
-
topLeft
.
y
,
equals
(
16.0
));
expect
(
topRight
.
x
-
avatarDTopRight
.
x
,
equals
(
16.0
));
expect
(
avatarDTopRight
.
y
-
topRight
.
y
,
equals
(
16.0
));
expect
(
avatarDTopRight
.
x
-
avatarCTopRight
.
x
,
equals
(
40.0
+
16.0
));
// size + space between
});
}
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