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
606f5622
Commit
606f5622
authored
Mar 24, 2017
by
Hans Muller
Committed by
GitHub
Mar 24, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Eliminated DrawerItem, use ListTile instead (#8992)
parent
51ea62c1
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
774 additions
and
653 deletions
+774
-653
main.dart
dev/benchmarks/complex_layout/lib/main.dart
+29
-41
card_collection.dart
dev/manual_tests/card_collection.dart
+34
-50
page_view.dart
dev/manual_tests/page_view.dart
+13
-17
drawer_demo.dart
examples/flutter_gallery/lib/demo/material/drawer_demo.dart
+12
-12
drawer.dart
examples/flutter_gallery/lib/gallery/drawer.dart
+86
-94
smoke_test.dart
examples/flutter_gallery/test/smoke_test.dart
+5
-1
stock_home.dart
examples/stocks/lib/stock_home.dart
+43
-37
stock_settings.dart
examples/stocks/lib/stock_settings.dart
+80
-120
icon_color_test.dart
examples/stocks/test/icon_color_test.dart
+3
-6
material.dart
packages/flutter/lib/material.dart
+0
-1
licenses.dart
packages/flutter/lib/src/foundation/licenses.dart
+2
-2
about.dart
packages/flutter/lib/src/material/about.dart
+15
-15
button.dart
packages/flutter/lib/src/material/button.dart
+1
-1
drawer.dart
packages/flutter/lib/src/material/drawer.dart
+36
-16
drawer_header.dart
packages/flutter/lib/src/material/drawer_header.dart
+1
-3
drawer_item.dart
packages/flutter/lib/src/material/drawer_item.dart
+0
-146
list_tile.dart
packages/flutter/lib/src/material/list_tile.dart
+173
-34
about_test.dart
packages/flutter/test/material/about_test.dart
+4
-4
drawer_test.dart
packages/flutter/test/material/drawer_test.dart
+3
-3
list_item_test.dart
packages/flutter/test/material/list_item_test.dart
+0
-50
list_tile_test.dart
packages/flutter/test/material/list_tile_test.dart
+234
-0
No files found.
dev/benchmarks/complex_layout/lib/main.dart
View file @
606f5622
...
@@ -577,53 +577,41 @@ class GalleryDrawer extends StatelessWidget {
...
@@ -577,53 +577,41 @@ class GalleryDrawer extends StatelessWidget {
child:
new
ListView
(
child:
new
ListView
(
children:
<
Widget
>[
children:
<
Widget
>[
new
FancyDrawerHeader
(),
new
FancyDrawerHeader
(),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
brightness_5
),
leading:
new
Icon
(
Icons
.
brightness_5
),
onPressed:
()
{
_changeTheme
(
context
,
true
);
},
title:
new
Text
(
'Light'
),
onTap:
()
{
_changeTheme
(
context
,
true
);
},
selected:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
selected:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
child:
new
Row
(
trailing:
new
Radio
<
bool
>(
children:
<
Widget
>[
value:
true
,
new
Expanded
(
child:
new
Text
(
'Light'
)),
groupValue:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
new
Radio
<
bool
>(
onChanged:
(
bool
value
)
{
_changeTheme
(
context
,
value
);
}
value:
true
,
),
groupValue:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
onChanged:
(
bool
value
)
{
_changeTheme
(
context
,
value
);
}
)
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
brightness_7
),
leading:
new
Icon
(
Icons
.
brightness_7
),
onPressed:
()
{
_changeTheme
(
context
,
false
);
},
title:
new
Text
(
'Dark'
),
onTap:
()
{
_changeTheme
(
context
,
false
);
},
selected:
!
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
selected:
!
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
child:
new
Row
(
trailing:
new
Radio
<
bool
>(
children:
<
Widget
>[
value:
false
,
new
Expanded
(
child:
new
Text
(
'Dark'
)),
groupValue:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
new
Radio
<
bool
>(
onChanged:
(
bool
value
)
{
_changeTheme
(
context
,
value
);
},
value:
false
,
),
groupValue:
ComplexLayoutApp
.
of
(
context
).
lightTheme
,
onChanged:
(
bool
value
)
{
_changeTheme
(
context
,
value
);
}
)
]
)
),
),
new
Divider
(),
new
Divider
(),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
hourglass_empty
),
leading:
new
Icon
(
Icons
.
hourglass_empty
),
title:
new
Text
(
'Animate Slowly'
),
selected:
timeDilation
!=
1.0
,
selected:
timeDilation
!=
1.0
,
onPressed:
()
{
ComplexLayoutApp
.
of
(
context
).
toggleAnimationSpeed
();
},
onTap:
()
{
ComplexLayoutApp
.
of
(
context
).
toggleAnimationSpeed
();
},
child:
new
Row
(
trailing:
new
Checkbox
(
children:
<
Widget
>[
value:
timeDilation
!=
1.0
,
new
Expanded
(
child:
new
Text
(
'Animate Slowly'
)),
onChanged:
(
bool
value
)
{
ComplexLayoutApp
.
of
(
context
).
toggleAnimationSpeed
();
}
new
Checkbox
(
),
value:
timeDilation
!=
1.0
,
),
onChanged:
(
bool
value
)
{
ComplexLayoutApp
.
of
(
context
).
toggleAnimationSpeed
();
}
],
)
),
]
)
)
]
)
);
);
}
}
}
}
...
...
dev/manual_tests/card_collection.dart
View file @
606f5622
...
@@ -107,10 +107,10 @@ class CardCollectionState extends State<CardCollection> {
...
@@ -107,10 +107,10 @@ class CardCollectionState extends State<CardCollection> {
buildFontRadioItem
(
"Center-align text"
,
TextAlign
.
center
,
_textAlign
,
_changeTextAlign
,
icon:
Icons
.
format_align_center
,
enabled:
!
_editable
),
buildFontRadioItem
(
"Center-align text"
,
TextAlign
.
center
,
_textAlign
,
_changeTextAlign
,
icon:
Icons
.
format_align_center
,
enabled:
!
_editable
),
buildFontRadioItem
(
"Right-align text"
,
TextAlign
.
right
,
_textAlign
,
_changeTextAlign
,
icon:
Icons
.
format_align_right
,
enabled:
!
_editable
),
buildFontRadioItem
(
"Right-align text"
,
TextAlign
.
right
,
_textAlign
,
_changeTextAlign
,
icon:
Icons
.
format_align_right
,
enabled:
!
_editable
),
new
Divider
(),
new
Divider
(),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
dvr
),
leading
:
new
Icon
(
Icons
.
dvr
),
on
Pressed
:
()
{
debugDumpApp
();
debugDumpRenderTree
();
},
on
Tap
:
()
{
debugDumpApp
();
debugDumpRenderTree
();
},
child
:
new
Text
(
'Dump App to Console'
),
title
:
new
Text
(
'Dump App to Console'
),
),
),
],
],
),
),
...
@@ -167,67 +167,51 @@ class CardCollectionState extends State<CardCollection> {
...
@@ -167,67 +167,51 @@ class CardCollectionState extends State<CardCollection> {
}
}
Widget
buildDrawerCheckbox
(
String
label
,
bool
value
,
void
callback
(),
{
bool
enabled:
true
})
{
Widget
buildDrawerCheckbox
(
String
label
,
bool
value
,
void
callback
(),
{
bool
enabled:
true
})
{
return
new
DrawerItem
(
return
new
ListTile
(
onPressed:
enabled
?
callback
:
null
,
onTap:
enabled
?
callback
:
null
,
child:
new
Row
(
title:
new
Text
(
label
),
children:
<
Widget
>[
trailing:
new
Checkbox
(
new
Expanded
(
child:
new
Text
(
label
)),
value:
value
,
new
Checkbox
(
onChanged:
enabled
?
(
_
)
{
callback
();
}
:
null
,
value:
value
,
onChanged:
enabled
?
(
_
)
{
callback
();
}
:
null
,
),
],
),
),
);
);
}
}
Widget
buildDrawerColorRadioItem
(
String
label
,
MaterialColor
itemValue
,
MaterialColor
currentValue
,
ValueChanged
<
MaterialColor
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
Widget
buildDrawerColorRadioItem
(
String
label
,
MaterialColor
itemValue
,
MaterialColor
currentValue
,
ValueChanged
<
MaterialColor
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
return
new
DrawerItem
(
return
new
ListTile
(
icon:
new
Icon
(
icon
),
leading:
new
Icon
(
icon
),
onPressed:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
title:
new
Text
(
label
),
child:
new
Row
(
onTap:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
children:
<
Widget
>[
trailing:
new
Radio
<
MaterialColor
>(
new
Expanded
(
child:
new
Text
(
label
)),
value:
itemValue
,
new
Radio
<
MaterialColor
>(
groupValue:
currentValue
,
value:
itemValue
,
onChanged:
enabled
?
onChanged
:
null
,
groupValue:
currentValue
,
onChanged:
enabled
?
onChanged
:
null
,
),
],
),
),
);
);
}
}
Widget
buildDrawerDirectionRadioItem
(
String
label
,
DismissDirection
itemValue
,
DismissDirection
currentValue
,
ValueChanged
<
DismissDirection
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
Widget
buildDrawerDirectionRadioItem
(
String
label
,
DismissDirection
itemValue
,
DismissDirection
currentValue
,
ValueChanged
<
DismissDirection
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
return
new
DrawerItem
(
return
new
ListTile
(
icon:
new
Icon
(
icon
),
leading:
new
Icon
(
icon
),
onPressed:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
title:
new
Text
(
label
),
child:
new
Row
(
onTap:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
children:
<
Widget
>[
trailing:
new
Radio
<
DismissDirection
>(
new
Expanded
(
child:
new
Text
(
label
)),
value:
itemValue
,
new
Radio
<
DismissDirection
>(
groupValue:
currentValue
,
value:
itemValue
,
onChanged:
enabled
?
onChanged
:
null
,
groupValue:
currentValue
,
onChanged:
enabled
?
onChanged
:
null
,
),
],
),
),
);
);
}
}
Widget
buildFontRadioItem
(
String
label
,
TextAlign
itemValue
,
TextAlign
currentValue
,
ValueChanged
<
TextAlign
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
Widget
buildFontRadioItem
(
String
label
,
TextAlign
itemValue
,
TextAlign
currentValue
,
ValueChanged
<
TextAlign
>
onChanged
,
{
IconData
icon
,
bool
enabled:
true
})
{
return
new
DrawerItem
(
return
new
ListTile
(
icon:
new
Icon
(
icon
),
leading:
new
Icon
(
icon
),
onPressed:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
title:
new
Text
(
label
),
child:
new
Row
(
onTap:
enabled
?
()
{
onChanged
(
itemValue
);
}
:
null
,
children:
<
Widget
>[
trailing:
new
Radio
<
TextAlign
>(
new
Expanded
(
child:
new
Text
(
label
)),
value:
itemValue
,
new
Radio
<
TextAlign
>(
groupValue:
currentValue
,
value:
itemValue
,
onChanged:
enabled
?
onChanged
:
null
,
groupValue:
currentValue
,
onChanged:
enabled
?
onChanged
:
null
,
),
],
),
),
);
);
}
}
...
...
dev/manual_tests/page_view.dart
View file @
606f5622
...
@@ -85,27 +85,23 @@ class PageViewAppState extends State<PageViewApp> {
...
@@ -85,27 +85,23 @@ class PageViewAppState extends State<PageViewApp> {
child:
new
ListView
(
child:
new
ListView
(
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerHeader
(
child:
new
Center
(
child:
new
Text
(
'Options'
))),
new
DrawerHeader
(
child:
new
Center
(
child:
new
Text
(
'Options'
))),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
more_horiz
),
leading
:
new
Icon
(
Icons
.
more_horiz
),
selected:
scrollDirection
==
Axis
.
horizontal
,
selected:
scrollDirection
==
Axis
.
horizontal
,
child
:
new
Text
(
'Horizontal Layout'
),
trailing
:
new
Text
(
'Horizontal Layout'
),
on
Pressed
:
switchScrollDirection
,
on
Tap
:
switchScrollDirection
,
),
),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
more_vert
),
leading
:
new
Icon
(
Icons
.
more_vert
),
selected:
scrollDirection
==
Axis
.
vertical
,
selected:
scrollDirection
==
Axis
.
vertical
,
child
:
new
Text
(
'Vertical Layout'
),
trailing
:
new
Text
(
'Vertical Layout'
),
on
Pressed
:
switchScrollDirection
,
on
Tap
:
switchScrollDirection
,
),
),
new
DrawerItem
(
new
ListTile
(
onPressed:
toggleItemsWrap
,
onTap:
toggleItemsWrap
,
child:
new
Row
(
title:
new
Text
(
'Scrolling wraps around'
),
children:
<
Widget
>[
// TODO(abarth): Actually make this checkbox change this value.
new
Expanded
(
child:
new
Text
(
'Scrolling wraps around'
)),
trailing:
new
Checkbox
(
value:
itemsWrap
,
onChanged:
null
),
// TODO(abarth): Actually make this checkbox change this value.
new
Checkbox
(
value:
itemsWrap
,
onChanged:
null
),
],
),
),
),
],
],
),
),
...
...
examples/flutter_gallery/lib/demo/material/drawer_demo.dart
View file @
606f5622
...
@@ -116,10 +116,10 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
...
@@ -116,10 +116,10 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
_drawerContents
.
map
((
String
id
)
{
children:
_drawerContents
.
map
((
String
id
)
{
return
new
DrawerItem
(
return
new
ListTile
(
icon
:
new
CircleAvatar
(
child:
new
Text
(
id
)),
leading
:
new
CircleAvatar
(
child:
new
Text
(
id
)),
child
:
new
Text
(
'Drawer item
$id
'
),
title
:
new
Text
(
'Drawer item
$id
'
),
on
Pressed
:
_showNotImplementedMessage
,
on
Tap
:
_showNotImplementedMessage
,
);
);
}).
toList
(),
}).
toList
(),
),
),
...
@@ -133,15 +133,15 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
...
@@ -133,15 +133,15 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
add
),
leading
:
new
Icon
(
Icons
.
add
),
child
:
new
Text
(
'Add account'
),
title
:
new
Text
(
'Add account'
),
on
Pressed
:
_showNotImplementedMessage
,
on
Tap
:
_showNotImplementedMessage
,
),
),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
settings
),
leading
:
new
Icon
(
Icons
.
settings
),
child
:
new
Text
(
'Manage accounts'
),
title
:
new
Text
(
'Manage accounts'
),
on
Pressed
:
_showNotImplementedMessage
,
on
Tap
:
_showNotImplementedMessage
,
),
),
],
],
),
),
...
...
examples/flutter_gallery/lib/gallery/drawer.dart
View file @
606f5622
...
@@ -126,96 +126,88 @@ class GalleryDrawer extends StatelessWidget {
...
@@ -126,96 +126,88 @@ class GalleryDrawer extends StatelessWidget {
final
TextStyle
aboutTextStyle
=
themeData
.
textTheme
.
body2
;
final
TextStyle
aboutTextStyle
=
themeData
.
textTheme
.
body2
;
final
TextStyle
linkStyle
=
themeData
.
textTheme
.
body2
.
copyWith
(
color:
themeData
.
accentColor
);
final
TextStyle
linkStyle
=
themeData
.
textTheme
.
body2
.
copyWith
(
color:
themeData
.
accentColor
);
final
Widget
lightThemeItem
=
new
DrawerItem
(
final
Widget
lightThemeItem
=
new
ListTile
(
icon:
new
Icon
(
Icons
.
brightness_5
),
leading:
new
Icon
(
Icons
.
brightness_5
),
onPressed:
()
{
onThemeChanged
(
true
);
},
title:
new
Text
(
'Light'
),
trailing:
new
Radio
<
bool
>(
value:
true
,
groupValue:
useLightTheme
,
onChanged:
onThemeChanged
,
),
selected:
useLightTheme
,
selected:
useLightTheme
,
child:
new
Row
(
onTap:
()
{
children:
<
Widget
>[
onThemeChanged
(
true
);
new
Expanded
(
child:
new
Text
(
'Light'
)),
},
new
Radio
<
bool
>(
value:
true
,
groupValue:
useLightTheme
,
onChanged:
onThemeChanged
)
]
)
);
);
final
Widget
darkThemeItem
=
new
DrawerItem
(
final
Widget
darkThemeItem
=
new
ListTile
(
icon:
new
Icon
(
Icons
.
brightness_7
),
leading:
new
Icon
(
Icons
.
brightness_7
),
onPressed:
()
{
onThemeChanged
(
false
);
},
title:
new
Text
(
'Dark'
),
selected:
useLightTheme
,
trailing:
new
Radio
<
bool
>(
child:
new
Row
(
value:
false
,
children:
<
Widget
>[
groupValue:
useLightTheme
,
new
Expanded
(
child:
new
Text
(
'Dark'
)),
onChanged:
onThemeChanged
new
Radio
<
bool
>(
),
value:
false
,
selected:
!
useLightTheme
,
groupValue:
useLightTheme
,
onTap:
()
{
onChanged:
onThemeChanged
onThemeChanged
(
false
);
)
},
]
)
);
);
final
Widget
mountainViewItem
=
new
DrawerItem
(
final
Widget
mountainViewItem
=
new
ListTile
(
// on iOS, we don't want to show an Android phone icon
// on iOS, we don't want to show an Android phone icon
icon:
new
Icon
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
?
Icons
.
star
:
Icons
.
phone_android
),
leading:
new
Icon
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
?
Icons
.
star
:
Icons
.
phone_android
),
onPressed:
()
{
onPlatformChanged
(
TargetPlatform
.
android
);
},
title:
new
Text
(
'Android'
),
trailing:
new
Radio
<
TargetPlatform
>(
value:
TargetPlatform
.
android
,
groupValue:
Theme
.
of
(
context
).
platform
,
onChanged:
onPlatformChanged
,
),
selected:
Theme
.
of
(
context
).
platform
==
TargetPlatform
.
android
,
selected:
Theme
.
of
(
context
).
platform
==
TargetPlatform
.
android
,
child:
new
Row
(
onTap:
()
{
children:
<
Widget
>[
onPlatformChanged
(
TargetPlatform
.
android
);
new
Expanded
(
child:
new
Text
(
'Android'
)),
},
new
Radio
<
TargetPlatform
>(
value:
TargetPlatform
.
android
,
groupValue:
Theme
.
of
(
context
).
platform
,
onChanged:
onPlatformChanged
,
)
]
)
);
);
final
Widget
cupertinoItem
=
new
DrawerItem
(
final
Widget
cupertinoItem
=
new
ListTile
(
// on iOS, we don't want to show the iPhone icon
// on iOS, we don't want to show the iPhone icon
icon:
new
Icon
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
?
Icons
.
star_border
:
Icons
.
phone_iphone
),
leading:
new
Icon
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
?
Icons
.
star_border
:
Icons
.
phone_iphone
),
onPressed:
()
{
onPlatformChanged
(
TargetPlatform
.
iOS
);
},
title:
new
Text
(
'iOS'
),
trailing:
new
Radio
<
TargetPlatform
>(
value:
TargetPlatform
.
iOS
,
groupValue:
Theme
.
of
(
context
).
platform
,
onChanged:
onPlatformChanged
,
),
selected:
Theme
.
of
(
context
).
platform
==
TargetPlatform
.
iOS
,
selected:
Theme
.
of
(
context
).
platform
==
TargetPlatform
.
iOS
,
child:
new
Row
(
onTap:
()
{
children:
<
Widget
>[
onPlatformChanged
(
TargetPlatform
.
iOS
);
new
Expanded
(
child:
new
Text
(
'iOS'
)),
},
new
Radio
<
TargetPlatform
>(
value:
TargetPlatform
.
iOS
,
groupValue:
Theme
.
of
(
context
).
platform
,
onChanged:
onPlatformChanged
,
)
]
)
);
);
final
Widget
animateSlowlyItem
=
new
DrawerItem
(
final
Widget
animateSlowlyItem
=
new
ListTile
(
icon:
new
Icon
(
Icons
.
hourglass_empty
),
leading:
new
Icon
(
Icons
.
hourglass_empty
),
title:
new
Text
(
'Animate Slowly'
),
trailing:
new
Checkbox
(
value:
timeDilation
!=
1.0
,
onChanged:
(
bool
value
)
{
onTimeDilationChanged
(
value
?
20.0
:
1.0
);
},
),
selected:
timeDilation
!=
1.0
,
selected:
timeDilation
!=
1.0
,
onPressed:
()
{
onTimeDilationChanged
(
timeDilation
!=
1.0
?
1.0
:
20.0
);
},
onTap:
()
{
child:
new
Row
(
onTimeDilationChanged
(
timeDilation
!=
1.0
?
1.0
:
20.0
);
children:
<
Widget
>[
},
new
Expanded
(
child:
new
Text
(
'Animate Slowly'
)),
new
Checkbox
(
value:
timeDilation
!=
1.0
,
onChanged:
(
bool
value
)
{
onTimeDilationChanged
(
value
?
20.0
:
1.0
);
}
)
]
)
);
);
final
Widget
sendFeedbackItem
=
new
DrawerItem
(
final
Widget
sendFeedbackItem
=
new
ListTile
(
icon:
new
Icon
(
Icons
.
report
),
leading:
new
Icon
(
Icons
.
report
),
onPressed:
onSendFeedback
??
()
{
title:
new
Text
(
'Send feedback'
),
onTap:
onSendFeedback
??
()
{
UrlLauncher
.
launch
(
'https://github.com/flutter/flutter/issues/new'
);
UrlLauncher
.
launch
(
'https://github.com/flutter/flutter/issues/new'
);
},
},
child:
new
Text
(
'Send feedback'
),
);
);
final
Widget
aboutItem
=
new
About
DrawerItem
(
final
Widget
aboutItem
=
new
About
ListTile
(
icon:
const
FlutterLogo
(),
icon:
const
FlutterLogo
(),
applicationVersion:
'2016 Q3 Preview'
,
applicationVersion:
'2016 Q3 Preview'
,
applicationIcon:
const
FlutterLogo
(),
applicationIcon:
const
FlutterLogo
(),
...
@@ -273,36 +265,36 @@ class GalleryDrawer extends StatelessWidget {
...
@@ -273,36 +265,36 @@ class GalleryDrawer extends StatelessWidget {
];
];
if
(
onShowPerformanceOverlayChanged
!=
null
)
{
if
(
onShowPerformanceOverlayChanged
!=
null
)
{
allDrawerItems
.
insert
(
8
,
new
DrawerItem
(
allDrawerItems
.
insert
(
8
,
new
ListTile
(
icon:
new
Icon
(
Icons
.
assessment
),
leading:
new
Icon
(
Icons
.
assessment
),
onPressed:
()
{
onShowPerformanceOverlayChanged
(!
showPerformanceOverlay
);
},
title:
new
Text
(
'Performance Overlay'
),
trailing:
new
Checkbox
(
value:
showPerformanceOverlay
,
onChanged:
(
bool
value
)
{
onShowPerformanceOverlayChanged
(!
showPerformanceOverlay
);
},
),
selected:
showPerformanceOverlay
,
selected:
showPerformanceOverlay
,
child:
new
Row
(
onTap:
()
{
children:
<
Widget
>[
onShowPerformanceOverlayChanged
(!
showPerformanceOverlay
);
new
Expanded
(
child:
new
Text
(
'Performance Overlay'
)),
},
new
Checkbox
(
value:
showPerformanceOverlay
,
onChanged:
(
bool
value
)
{
onShowPerformanceOverlayChanged
(!
showPerformanceOverlay
);
}
)
]
)
));
));
}
}
if
(
onCheckerboardRasterCacheImagesChanged
!=
null
)
{
if
(
onCheckerboardRasterCacheImagesChanged
!=
null
)
{
allDrawerItems
.
insert
(
8
,
new
DrawerItem
(
allDrawerItems
.
insert
(
8
,
new
ListTile
(
icon:
new
Icon
(
Icons
.
assessment
),
leading:
new
Icon
(
Icons
.
assessment
),
onPressed:
()
{
onCheckerboardRasterCacheImagesChanged
(!
checkerboardRasterCacheImages
);
},
title:
new
Text
(
'Checkerboard Raster Cache Images'
),
trailing:
new
Checkbox
(
value:
checkerboardRasterCacheImages
,
onChanged:
(
bool
value
)
{
onCheckerboardRasterCacheImagesChanged
(!
checkerboardRasterCacheImages
);
},
),
selected:
checkerboardRasterCacheImages
,
selected:
checkerboardRasterCacheImages
,
child:
new
Row
(
onTap:
()
{
children:
<
Widget
>[
onCheckerboardRasterCacheImagesChanged
(!
checkerboardRasterCacheImages
);
new
Expanded
(
child:
new
Text
(
'Checkerboard Raster Cache Images'
)),
},
new
Checkbox
(
value:
checkerboardRasterCacheImages
,
onChanged:
(
bool
value
)
{
onCheckerboardRasterCacheImagesChanged
(!
checkerboardRasterCacheImages
);
}
)
]
)
));
));
}
}
...
...
examples/flutter_gallery/test/smoke_test.dart
View file @
606f5622
...
@@ -131,7 +131,6 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
...
@@ -131,7 +131,6 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
await
smokeDemo
(
tester
,
routeName
);
await
smokeDemo
(
tester
,
routeName
);
tester
.
binding
.
debugAssertNoTransientCallbacks
(
'A transient callback was still active after leaving route
$routeName
'
);
tester
.
binding
.
debugAssertNoTransientCallbacks
(
'A transient callback was still active after leaving route
$routeName
'
);
}
}
expect
(
errors
,
0
);
expect
(
errors
,
0
);
final
Finder
navigationMenuButton
=
find
.
byTooltip
(
'Open navigation menu'
);
final
Finder
navigationMenuButton
=
find
.
byTooltip
(
'Open navigation menu'
);
...
@@ -150,6 +149,11 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
...
@@ -150,6 +149,11 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
await
tester
.
pump
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Wait until it's changed.
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Wait until it's changed.
// scroll the 'Send feedback' item into view
await
tester
.
drag
(
find
.
text
(
'Light'
),
const
Offset
(
0.0
,
-
200.0
));
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Wait until it's changed.
// send feedback
// send feedback
expect
(
hasFeedback
,
false
);
expect
(
hasFeedback
,
false
);
await
tester
.
tap
(
find
.
text
(
'Send feedback'
));
await
tester
.
tap
(
find
.
text
(
'Send feedback'
));
...
...
examples/stocks/lib/stock_home.dart
View file @
606f5622
...
@@ -124,19 +124,20 @@ class StockHomeState extends State<StockHome> {
...
@@ -124,19 +124,20 @@ class StockHomeState extends State<StockHome> {
child:
new
ListView
(
child:
new
ListView
(
children:
<
Widget
>[
children:
<
Widget
>[
new
DrawerHeader
(
child:
new
Center
(
child:
new
Text
(
'Stocks'
))),
new
DrawerHeader
(
child:
new
Center
(
child:
new
Text
(
'Stocks'
))),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
assessment
),
leading:
new
Icon
(
Icons
.
assessment
),
title:
new
Text
(
'Stock List'
),
selected:
true
,
selected:
true
,
child:
new
Text
(
'Stock List'
)
),
),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
account_balance
),
leading
:
new
Icon
(
Icons
.
account_balance
),
onPressed:
null
,
title:
new
Text
(
'Account Balance'
)
,
child:
new
Text
(
'Account Balance'
)
enabled:
false
,
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
dvr
),
leading:
new
Icon
(
Icons
.
dvr
),
onPressed:
()
{
title:
new
Text
(
'Dump App to Console'
),
onTap:
()
{
try
{
try
{
debugDumpApp
();
debugDumpApp
();
debugDumpRenderTree
();
debugDumpRenderTree
();
...
@@ -146,38 +147,43 @@ class StockHomeState extends State<StockHome> {
...
@@ -146,38 +147,43 @@ class StockHomeState extends State<StockHome> {
debugPrint
(
'Exception while dumping app:
\n
$e
\n
$stack
'
);
debugPrint
(
'Exception while dumping app:
\n
$e
\n
$stack
'
);
}
}
},
},
child:
new
Text
(
'Dump App to Console'
)
),
),
new
Divider
(),
new
Divider
(),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
thumb_up
),
leading:
new
Icon
(
Icons
.
thumb_up
),
onPressed:
()
=>
_handleStockModeChange
(
StockMode
.
optimistic
),
title:
new
Text
(
'Optimistic'
),
child:
new
Row
(
trailing:
new
Radio
<
StockMode
>(
children:
<
Widget
>[
value:
StockMode
.
optimistic
,
new
Expanded
(
child:
new
Text
(
'Optimistic'
)),
groupValue:
config
.
configuration
.
stockMode
,
new
Radio
<
StockMode
>(
value:
StockMode
.
optimistic
,
groupValue:
config
.
configuration
.
stockMode
,
onChanged:
_handleStockModeChange
)
onChanged:
_handleStockModeChange
]
),
)
onTap:
()
{
_handleStockModeChange
(
StockMode
.
optimistic
);
},
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
thumb_down
),
leading:
new
Icon
(
Icons
.
thumb_down
),
onPressed:
()
=>
_handleStockModeChange
(
StockMode
.
pessimistic
),
title:
new
Text
(
'Pessimistic'
),
child:
new
Row
(
trailing:
new
Radio
<
StockMode
>(
children:
<
Widget
>[
value:
StockMode
.
pessimistic
,
new
Expanded
(
child:
new
Text
(
'Pessimistic'
)),
groupValue:
config
.
configuration
.
stockMode
,
new
Radio
<
StockMode
>(
value:
StockMode
.
pessimistic
,
groupValue:
config
.
configuration
.
stockMode
,
onChanged:
_handleStockModeChange
)
onChanged:
_handleStockModeChange
]
),
)
onTap:
()
{
_handleStockModeChange
(
StockMode
.
pessimistic
);
},
),
),
new
Divider
(),
new
Divider
(),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
settings
),
leading:
new
Icon
(
Icons
.
settings
),
onPressed:
_handleShowSettings
,
title:
new
Text
(
'Settings'
),
child:
new
Text
(
'Settings'
)),
onTap:
_handleShowSettings
,
new
DrawerItem
(
),
icon:
new
Icon
(
Icons
.
help
),
new
ListTile
(
onPressed:
_handleShowAbout
,
leading:
new
Icon
(
Icons
.
help
),
child:
new
Text
(
'About'
))
title:
new
Text
(
'About'
),
onTap:
_handleShowAbout
,
),
]
]
)
)
);
);
...
...
examples/stocks/lib/stock_settings.dart
View file @
606f5622
...
@@ -103,139 +103,99 @@ class StockSettingsState extends State<StockSettings> {
...
@@ -103,139 +103,99 @@ class StockSettingsState extends State<StockSettings> {
Widget
buildSettingsPane
(
BuildContext
context
)
{
Widget
buildSettingsPane
(
BuildContext
context
)
{
final
List
<
Widget
>
rows
=
<
Widget
>[
final
List
<
Widget
>
rows
=
<
Widget
>[
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
thumb_up
),
leading:
new
Icon
(
Icons
.
thumb_up
),
onPressed:
_confirmOptimismChange
,
title:
new
Text
(
'Everything is awesome'
),
child:
new
Row
(
onTap:
_confirmOptimismChange
,
children:
<
Widget
>[
trailing:
new
Checkbox
(
new
Expanded
(
child:
new
Text
(
'Everything is awesome'
)),
value:
config
.
configuration
.
stockMode
==
StockMode
.
optimistic
,
new
Checkbox
(
onChanged:
(
bool
value
)
=>
_confirmOptimismChange
(),
value:
config
.
configuration
.
stockMode
==
StockMode
.
optimistic
,
),
onChanged:
(
bool
value
)
=>
_confirmOptimismChange
()
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
backup
),
leading:
new
Icon
(
Icons
.
backup
),
onPressed:
()
{
_handleBackupChanged
(!(
config
.
configuration
.
backupMode
==
BackupMode
.
enabled
));
},
title:
new
Text
(
'Back up stock list to the cloud'
),
child:
new
Row
(
onTap:
()
{
_handleBackupChanged
(!(
config
.
configuration
.
backupMode
==
BackupMode
.
enabled
));
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Back up stock list to the cloud'
)),
value:
config
.
configuration
.
backupMode
==
BackupMode
.
enabled
,
new
Switch
(
onChanged:
_handleBackupChanged
,
value:
config
.
configuration
.
backupMode
==
BackupMode
.
enabled
,
),
onChanged:
_handleBackupChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
picture_in_picture
),
leading:
new
Icon
(
Icons
.
picture_in_picture
),
onPressed:
()
{
_handleShowPerformanceOverlayChanged
(!
config
.
configuration
.
showPerformanceOverlay
);
},
title:
new
Text
(
'Show rendering performance overlay'
),
child:
new
Row
(
onTap:
()
{
_handleShowPerformanceOverlayChanged
(!
config
.
configuration
.
showPerformanceOverlay
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show rendering performance overlay'
)),
value:
config
.
configuration
.
showPerformanceOverlay
,
new
Switch
(
onChanged:
_handleShowPerformanceOverlayChanged
,
value:
config
.
configuration
.
showPerformanceOverlay
,
),
onChanged:
_handleShowPerformanceOverlayChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
accessibility
),
leading:
new
Icon
(
Icons
.
accessibility
),
onPressed:
()
{
_handleShowSemanticsDebuggerChanged
(!
config
.
configuration
.
showSemanticsDebugger
);
},
title:
new
Text
(
'Show semantics overlay'
),
child:
new
Row
(
onTap:
()
{
_handleShowSemanticsDebuggerChanged
(!
config
.
configuration
.
showSemanticsDebugger
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show semantics overlay'
)),
value:
config
.
configuration
.
showSemanticsDebugger
,
new
Switch
(
onChanged:
_handleShowSemanticsDebuggerChanged
,
value:
config
.
configuration
.
showSemanticsDebugger
,
),
onChanged:
_handleShowSemanticsDebuggerChanged
),
]
)
),
),
];
];
assert
(()
{
assert
(()
{
// material grid and size construction lines are only available in checked mode
// material grid and size construction lines are only available in checked mode
rows
.
addAll
(<
Widget
>[
rows
.
addAll
(<
Widget
>[
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
border_clear
),
leading:
new
Icon
(
Icons
.
border_clear
),
onPressed:
()
{
_handleShowGridChanged
(!
config
.
configuration
.
debugShowGrid
);
},
title:
new
Text
(
'Show material grid (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowGridChanged
(!
config
.
configuration
.
debugShowGrid
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show material grid (for debugging)'
)),
value:
config
.
configuration
.
debugShowGrid
,
new
Switch
(
onChanged:
_handleShowGridChanged
,
value:
config
.
configuration
.
debugShowGrid
,
),
onChanged:
_handleShowGridChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
border_all
),
leading:
new
Icon
(
Icons
.
border_all
),
onPressed:
()
{
_handleShowSizesChanged
(!
config
.
configuration
.
debugShowSizes
);
},
title:
new
Text
(
'Show construction lines (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowSizesChanged
(!
config
.
configuration
.
debugShowSizes
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show construction lines (for debugging)'
)),
value:
config
.
configuration
.
debugShowSizes
,
new
Switch
(
onChanged:
_handleShowSizesChanged
,
value:
config
.
configuration
.
debugShowSizes
,
),
onChanged:
_handleShowSizesChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
format_color_text
),
leading:
new
Icon
(
Icons
.
format_color_text
),
onPressed:
()
{
_handleShowBaselinesChanged
(!
config
.
configuration
.
debugShowBaselines
);
},
title:
new
Text
(
'Show baselines (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowBaselinesChanged
(!
config
.
configuration
.
debugShowBaselines
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show baselines (for debugging)'
)),
value:
config
.
configuration
.
debugShowBaselines
,
new
Switch
(
onChanged:
_handleShowBaselinesChanged
,
value:
config
.
configuration
.
debugShowBaselines
,
),
onChanged:
_handleShowBaselinesChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
filter_none
),
leading:
new
Icon
(
Icons
.
filter_none
),
onPressed:
()
{
_handleShowLayersChanged
(!
config
.
configuration
.
debugShowLayers
);
},
title:
new
Text
(
'Show layer boundaries (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowLayersChanged
(!
config
.
configuration
.
debugShowLayers
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show layer boundaries (for debugging)'
)),
value:
config
.
configuration
.
debugShowLayers
,
new
Switch
(
onChanged:
_handleShowLayersChanged
,
value:
config
.
configuration
.
debugShowLayers
,
),
onChanged:
_handleShowLayersChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
mouse
),
leading:
new
Icon
(
Icons
.
mouse
),
onPressed:
()
{
_handleShowPointersChanged
(!
config
.
configuration
.
debugShowPointers
);
},
title:
new
Text
(
'Show pointer hit-testing (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowPointersChanged
(!
config
.
configuration
.
debugShowPointers
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show pointer hit-testing (for debugging)'
)),
value:
config
.
configuration
.
debugShowPointers
,
new
Switch
(
onChanged:
_handleShowPointersChanged
,
value:
config
.
configuration
.
debugShowPointers
,
),
onChanged:
_handleShowPointersChanged
),
]
)
),
),
new
DrawerItem
(
new
ListTile
(
icon:
new
Icon
(
Icons
.
gradient
),
leading:
new
Icon
(
Icons
.
gradient
),
onPressed:
()
{
_handleShowRainbowChanged
(!
config
.
configuration
.
debugShowRainbow
);
},
title:
new
Text
(
'Show repaint rainbow (for debugging)'
),
child:
new
Row
(
onTap:
()
{
_handleShowRainbowChanged
(!
config
.
configuration
.
debugShowRainbow
);
},
children:
<
Widget
>[
trailing:
new
Switch
(
new
Expanded
(
child:
new
Text
(
'Show repaint rainbow (for debugging)'
)),
value:
config
.
configuration
.
debugShowRainbow
,
new
Switch
(
onChanged:
_handleShowRainbowChanged
,
value:
config
.
configuration
.
debugShowRainbow
,
),
onChanged:
_handleShowRainbowChanged
),
]
)
),
),
]);
]);
return
true
;
return
true
;
...
...
examples/stocks/test/icon_color_test.dart
View file @
606f5622
...
@@ -38,12 +38,9 @@ Element findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
...
@@ -38,12 +38,9 @@ Element findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
final
RegExp
materialIconAssetNameColorExtractor
=
new
RegExp
(
r'[^/]+/ic_.+_(white|black)_[0-9]+dp\.png'
);
final
RegExp
materialIconAssetNameColorExtractor
=
new
RegExp
(
r'[^/]+/ic_.+_(white|black)_[0-9]+dp\.png'
);
void
checkIconColor
(
WidgetTester
tester
,
String
label
,
Color
color
)
{
void
checkIconColor
(
WidgetTester
tester
,
String
label
,
Color
color
)
{
// The icon is going to be in the same merged semantics box as the text
final
Element
listTile
=
findElementOfExactWidgetTypeGoingUp
(
tester
.
element
(
find
.
text
(
label
)),
ListTile
);
// regardless of how the menu item is represented, so this is a good
expect
(
listTile
,
isNotNull
);
// way to find the menu item. I hope.
final
Element
asset
=
findElementOfExactWidgetTypeGoingDown
(
listTile
,
RichText
);
final
Element
semantics
=
findElementOfExactWidgetTypeGoingUp
(
tester
.
element
(
find
.
text
(
label
)),
MergeSemantics
);
expect
(
semantics
,
isNotNull
);
final
Element
asset
=
findElementOfExactWidgetTypeGoingDown
(
semantics
,
RichText
);
final
RichText
richText
=
asset
.
widget
;
final
RichText
richText
=
asset
.
widget
;
expect
(
richText
.
text
.
style
.
color
,
equals
(
color
));
expect
(
richText
.
text
.
style
.
color
,
equals
(
color
));
}
}
...
...
packages/flutter/lib/material.dart
View file @
606f5622
...
@@ -34,7 +34,6 @@ export 'src/material/dialog.dart';
...
@@ -34,7 +34,6 @@ export 'src/material/dialog.dart';
export
'src/material/divider.dart'
;
export
'src/material/divider.dart'
;
export
'src/material/drawer.dart'
;
export
'src/material/drawer.dart'
;
export
'src/material/drawer_header.dart'
;
export
'src/material/drawer_header.dart'
;
export
'src/material/drawer_item.dart'
;
export
'src/material/dropdown.dart'
;
export
'src/material/dropdown.dart'
;
export
'src/material/expand_icon.dart'
;
export
'src/material/expand_icon.dart'
;
export
'src/material/expansion_panel.dart'
;
export
'src/material/expansion_panel.dart'
;
...
...
packages/flutter/lib/src/foundation/licenses.dart
View file @
606f5622
...
@@ -257,8 +257,8 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
...
@@ -257,8 +257,8 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
/// * [showAboutDialog], which shows a Material-style dialog with information
/// * [showAboutDialog], which shows a Material-style dialog with information
/// about the application, including a button that shows a [LicensePage] that
/// about the application, including a button that shows a [LicensePage] that
/// uses this API to select licenses to show.
/// uses this API to select licenses to show.
/// * [About
DrawerItem], which is a widget to put in a [Drawer] which
/// * [About
ListTile], which is a widget that can be added to a [Drawer]. When
///
automatically
calls [showAboutDialog].
///
tapped it
calls [showAboutDialog].
class
LicenseRegistry
{
class
LicenseRegistry
{
LicenseRegistry
.
_
();
LicenseRegistry
.
_
();
...
...
packages/flutter/lib/src/material/about.dart
View file @
606f5622
...
@@ -11,21 +11,21 @@ import 'package:flutter/foundation.dart';
...
@@ -11,21 +11,21 @@ import 'package:flutter/foundation.dart';
import
'app_bar.dart'
;
import
'app_bar.dart'
;
import
'debug.dart'
;
import
'debug.dart'
;
import
'dialog.dart'
;
import
'dialog.dart'
;
import
'drawer_item.dart'
;
import
'flat_button.dart'
;
import
'flat_button.dart'
;
import
'icon.dart'
;
import
'icon.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'icon_theme_data.dart'
;
import
'list_tile.dart'
;
import
'page.dart'
;
import
'page.dart'
;
import
'progress_indicator.dart'
;
import
'progress_indicator.dart'
;
import
'scaffold.dart'
;
import
'scaffold.dart'
;
import
'scrollbar.dart'
;
import
'scrollbar.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
/// A [
DrawerItem] to show
an about box.
/// A [
ListTile] that shows
an about box.
///
///
///
Place this in a [Drawer], specifying your preferred application name,
///
This widget is often added to an app's [Drawer]. When tapped it shows
///
version, icon, and copyright in the appropriate fields
.
///
an about box dialog with [showAboutDialog]
.
///
///
/// The about box will include a button that shows licenses for software used by
/// The about box will include a button that shows licenses for software used by
/// the application. The licenses shown are those returned by the
/// the application. The licenses shown are those returned by the
...
@@ -33,13 +33,13 @@ import 'theme.dart';
...
@@ -33,13 +33,13 @@ import 'theme.dart';
///
///
/// If your application does not have a [Drawer], you should provide an
/// If your application does not have a [Drawer], you should provide an
/// affordance to call [showAboutDialog] or (at least) [showLicensePage].
/// affordance to call [showAboutDialog] or (at least) [showLicensePage].
class
About
DrawerItem
extends
StatelessWidget
{
class
About
ListTile
extends
StatelessWidget
{
/// Creates a
drawer item
for showing an about box.
/// Creates a
list tile
for showing an about box.
///
///
/// The arguments are all optional. The application name, if omitted, will be
/// The arguments are all optional. The application name, if omitted, will be
/// derived from the nearest [Title] widget. The version, icon, and legalese
/// derived from the nearest [Title] widget. The version, icon, and legalese
/// values default to the empty string.
/// values default to the empty string.
About
DrawerItem
({
About
ListTile
({
Key
key
,
Key
key
,
this
.
icon
:
const
Icon
(
null
),
this
.
icon
:
const
Icon
(
null
),
this
.
child
,
this
.
child
,
...
@@ -109,10 +109,10 @@ class AboutDrawerItem extends StatelessWidget {
...
@@ -109,10 +109,10 @@ class AboutDrawerItem extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
assert
(
debugCheckHasMaterial
(
context
));
return
new
DrawerItem
(
return
new
ListTile
(
icon
:
icon
,
leading
:
icon
,
child
:
child
??
new
Text
(
'About
${applicationName ?? _defaultApplicationName(context)}
'
),
title
:
child
??
new
Text
(
'About
${applicationName ?? _defaultApplicationName(context)}
'
),
on
Pressed
:
()
{
on
Tap
:
()
{
showAboutDialog
(
showAboutDialog
(
context:
context
,
context:
context
,
applicationName:
applicationName
,
applicationName:
applicationName
,
...
@@ -131,7 +131,7 @@ class AboutDrawerItem extends StatelessWidget {
...
@@ -131,7 +131,7 @@ class AboutDrawerItem extends StatelessWidget {
///
///
/// The arguments correspond to the properties on [AboutDialog].
/// The arguments correspond to the properties on [AboutDialog].
///
///
/// If the application has a [Drawer], consider using [About
DrawerItem
] instead
/// If the application has a [Drawer], consider using [About
ListTile
] instead
/// of calling this directly.
/// of calling this directly.
///
///
/// If you do not need an about box in your application, you should at least
/// If you do not need an about box in your application, you should at least
...
@@ -164,7 +164,7 @@ void showAboutDialog({
...
@@ -164,7 +164,7 @@ void showAboutDialog({
///
///
/// The arguments correspond to the properties on [LicensePage].
/// The arguments correspond to the properties on [LicensePage].
///
///
/// If the application has a [Drawer], consider using [About
DrawerItem
] instead
/// If the application has a [Drawer], consider using [About
ListTile
] instead
/// of calling this directly.
/// of calling this directly.
///
///
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
...
@@ -196,7 +196,7 @@ void showLicensePage({
...
@@ -196,7 +196,7 @@ void showLicensePage({
///
///
/// To show an [AboutDialog], use [showAboutDialog].
/// To show an [AboutDialog], use [showAboutDialog].
///
///
/// If the application has a [Drawer], the [About
DrawerItem
] widget can make the
/// If the application has a [Drawer], the [About
ListTile
] widget can make the
/// process of showing an about dialog simpler.
/// process of showing an about dialog simpler.
///
///
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
...
@@ -316,7 +316,7 @@ class AboutDialog extends StatelessWidget {
...
@@ -316,7 +316,7 @@ class AboutDialog extends StatelessWidget {
///
///
/// To show a [LicensePage], use [showLicensePage].
/// To show a [LicensePage], use [showLicensePage].
///
///
/// The [AboutDialog] shown by [showAboutDialog] and [About
DrawerItem
] includes
/// The [AboutDialog] shown by [showAboutDialog] and [About
ListTile
] includes
/// a button that calls [showLicensePage].
/// a button that calls [showLicensePage].
///
///
/// The licenses shown on the [LicensePage] are those returned by the
/// The licenses shown on the [LicensePage] are those returned by the
...
...
packages/flutter/lib/src/material/button.dart
View file @
606f5622
...
@@ -92,7 +92,7 @@ class ButtonTheme extends InheritedWidget {
...
@@ -92,7 +92,7 @@ class ButtonTheme extends InheritedWidget {
/// Defaults to 16.0 pixels of horizontal padding.
/// Defaults to 16.0 pixels of horizontal padding.
final
EdgeInsets
padding
;
final
EdgeInsets
padding
;
/// The c
olor from the c
losest instance of this class that encloses the given context.
/// The closest instance of this class that encloses the given context.
///
///
/// Typical usage is as follows:
/// Typical usage is as follows:
///
///
...
...
packages/flutter/lib/src/material/drawer.dart
View file @
606f5622
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'colors.dart'
;
import
'list_tile.dart'
;
import
'material.dart'
;
import
'material.dart'
;
// TODO(eseidel): Draw width should vary based on device size:
// TODO(eseidel): Draw width should vary based on device size:
...
@@ -30,7 +31,23 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
...
@@ -30,7 +31,23 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
///
///
/// Drawers are typically used with the [Scaffold.drawer] property. The child of
/// Drawers are typically used with the [Scaffold.drawer] property. The child of
/// the drawer is usually a [ListView] whose first child is a [DrawerHeader]
/// the drawer is usually a [ListView] whose first child is a [DrawerHeader]
/// that displays status information about the current user.
/// that displays status information about the current user. The remaining
/// drawer children are often constructed with [ListTile]s, often concluding
/// with an [AboutListTile].
///
/// An open drawer can be closed by calling [Navigator.pop]. For example
/// a drawer item might close the drawer when tapped:
///
/// ```dart
/// new ListTile(
/// leading: new Icon(Icons.change_history),
/// title: new Text('Change history'),
/// onTap: () {
/// // change app state...
/// Navigator.pop(context); // close the drawer
/// },
/// );
/// ```
///
///
/// The [AppBar] automatically displays an appropriate [IconButton] to show the
/// The [AppBar] automatically displays an appropriate [IconButton] to show the
/// [Drawer] when a [Drawer] is available in the [Scaffold]. The [Scaffold]
/// [Drawer] when a [Drawer] is available in the [Scaffold]. The [Scaffold]
...
@@ -43,9 +60,6 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
...
@@ -43,9 +60,6 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
/// * [Scaffold.of], to obtain the current [ScaffoldState], which manages the
/// * [Scaffold.of], to obtain the current [ScaffoldState], which manages the
/// display and animation of the drawer.
/// display and animation of the drawer.
/// * [ScaffoldState.openDrawer], which displays its [Drawer], if any.
/// * [ScaffoldState.openDrawer], which displays its [Drawer], if any.
/// * [Navigator.pop], which closes the drawer if it is open.
/// * [DrawerItem], a widget for items in drawers.
/// * [DrawerHeader], a widget for the top part of a drawer.
/// * <https://material.google.com/patterns/navigation-drawer.html>
/// * <https://material.google.com/patterns/navigation-drawer.html>
class
Drawer
extends
StatelessWidget
{
class
Drawer
extends
StatelessWidget
{
/// Creates a material design drawer.
/// Creates a material design drawer.
...
@@ -233,8 +247,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
...
@@ -233,8 +247,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
final
ColorTween
_color
=
new
ColorTween
(
begin:
Colors
.
transparent
,
end:
Colors
.
black54
);
final
ColorTween
_color
=
new
ColorTween
(
begin:
Colors
.
transparent
,
end:
Colors
.
black54
);
final
GlobalKey
_gestureDetectorKey
=
new
GlobalKey
();
final
GlobalKey
_gestureDetectorKey
=
new
GlobalKey
();
@override
Widget
_buildDrawer
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
if
(
_controller
.
status
==
AnimationStatus
.
dismissed
)
{
if
(
_controller
.
status
==
AnimationStatus
.
dismissed
)
{
return
new
Align
(
return
new
Align
(
alignment:
FractionalOffset
.
centerLeft
,
alignment:
FractionalOffset
.
centerLeft
,
...
@@ -245,7 +258,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
...
@@ -245,7 +258,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
behavior:
HitTestBehavior
.
translucent
,
behavior:
HitTestBehavior
.
translucent
,
excludeFromSemantics:
true
,
excludeFromSemantics:
true
,
child:
new
Container
(
width:
_kEdgeDragWidth
)
child:
new
Container
(
width:
_kEdgeDragWidth
)
)
)
,
);
);
}
else
{
}
else
{
return
new
GestureDetector
(
return
new
GestureDetector
(
...
@@ -263,8 +276,8 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
...
@@ -263,8 +276,8 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
decoration:
new
BoxDecoration
(
decoration:
new
BoxDecoration
(
backgroundColor:
_color
.
evaluate
(
_controller
)
backgroundColor:
_color
.
evaluate
(
_controller
)
),
),
child:
new
Container
()
child:
new
Container
()
,
)
)
,
),
),
new
Align
(
new
Align
(
alignment:
FractionalOffset
.
centerLeft
,
alignment:
FractionalOffset
.
centerLeft
,
...
@@ -275,14 +288,21 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
...
@@ -275,14 +288,21 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
child:
new
Focus
(
child:
new
Focus
(
key:
_drawerKey
,
key:
_drawerKey
,
child:
config
.
child
child:
config
.
child
)
)
,
)
)
,
)
)
,
)
)
,
]
]
,
)
)
,
)
)
,
);
);
}
}
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
ListTileTheme
(
style:
ListTileStyle
.
drawer
,
child:
_buildDrawer
(
context
),
);
}
}
}
packages/flutter/lib/src/material/drawer_header.dart
View file @
606f5622
...
@@ -17,14 +17,12 @@ const double _kDrawerHeaderHeight = 160.0 + 1.0; // bottom edge
...
@@ -17,14 +17,12 @@ const double _kDrawerHeaderHeight = 160.0 + 1.0; // bottom edge
/// Part of the material design [Drawer].
/// Part of the material design [Drawer].
///
///
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// satisfied by putting the [Drawer
Item
] in a [Drawer].
/// satisfied by putting the [Drawer
Header
] in a [Drawer].
///
///
/// See also:
/// See also:
///
///
/// * [Drawer]
/// * [UserAccountsDrawerHeader], a variant of [DrawerHeader] that is
/// * [UserAccountsDrawerHeader], a variant of [DrawerHeader] that is
/// specialized for showing user accounts.
/// specialized for showing user accounts.
/// * [DrawerItem]
/// * <https://material.google.com/patterns/navigation-drawer.html>
/// * <https://material.google.com/patterns/navigation-drawer.html>
class
DrawerHeader
extends
StatelessWidget
{
class
DrawerHeader
extends
StatelessWidget
{
/// Creates a material design drawer header.
/// Creates a material design drawer header.
...
...
packages/flutter/lib/src/material/drawer_item.dart
deleted
100644 → 0
View file @
51ea62c1
// 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/foundation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'constants.dart'
;
import
'debug.dart'
;
import
'icon.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'image_icon.dart'
;
import
'ink_well.dart'
;
import
'theme.dart'
;
/// An item in a material design drawer.
///
/// Part of the material design [Drawer].
///
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// satisfied by putting the [DrawerItem] in a [Drawer].
///
/// See also:
///
/// * [Drawer]
/// * [DrawerHeader]
/// * <https://material.google.com/patterns/navigation-drawer.html>
class
DrawerItem
extends
StatelessWidget
{
/// Creates a material design drawer item.
///
/// Requires one of its ancestors to be a [Material] widget.
const
DrawerItem
({
Key
key
,
this
.
icon
:
const
Icon
(
null
),
@required
this
.
child
,
this
.
onPressed
,
this
.
selected
:
false
})
:
super
(
key:
key
);
/// The icon to display before the child widget.
///
/// The size and color of the icon is configured automatically using an
/// [IconTheme] and therefore do not need to be explicitly given in the
/// icon widget.
///
/// See [Icon], [ImageIcon].
final
Widget
icon
;
/// The widget below this widget in the tree.
final
Widget
child
;
/// Called when the user taps this drawer item.
///
/// If null, the drawer item is displayed as disabled.
///
/// To close the [Drawer] when an item is pressed, call [Navigator.pop].
final
VoidCallback
onPressed
;
/// Whether this drawer item is currently selected.
///
/// The currently selected item is highlighted to distinguish it from other
/// drawer items.
final
bool
selected
;
Color
_getIconColor
(
ThemeData
themeData
)
{
switch
(
themeData
.
brightness
)
{
case
Brightness
.
light
:
if
(
selected
)
return
themeData
.
primaryColor
;
if
(
onPressed
==
null
)
return
Colors
.
black26
;
return
Colors
.
black45
;
case
Brightness
.
dark
:
if
(
selected
)
return
themeData
.
accentColor
;
if
(
onPressed
==
null
)
return
Colors
.
white30
;
return
null
;
// use default icon theme color unmodified
}
assert
(
themeData
.
brightness
!=
null
);
return
null
;
}
TextStyle
_getTextStyle
(
ThemeData
themeData
)
{
final
TextStyle
result
=
themeData
.
textTheme
.
body2
;
if
(
selected
)
{
switch
(
themeData
.
brightness
)
{
case
Brightness
.
light
:
return
result
.
copyWith
(
color:
themeData
.
primaryColor
);
case
Brightness
.
dark
:
return
result
.
copyWith
(
color:
themeData
.
accentColor
);
}
}
return
result
;
}
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
final
ThemeData
themeData
=
Theme
.
of
(
context
);
final
List
<
Widget
>
children
=
<
Widget
>[];
if
(
icon
!=
null
)
{
children
.
add
(
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
child:
new
IconTheme
.
merge
(
context:
context
,
data:
new
IconThemeData
(
color:
_getIconColor
(
themeData
),
size:
24.0
),
child:
icon
)
)
);
}
if
(
child
!=
null
)
{
children
.
add
(
new
Expanded
(
child:
new
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
child:
new
AnimatedDefaultTextStyle
(
style:
_getTextStyle
(
themeData
),
duration:
kThemeChangeDuration
,
child:
child
)
)
)
);
}
return
new
MergeSemantics
(
child:
new
Container
(
height:
48.0
,
child:
new
InkWell
(
onTap:
onPressed
,
child:
new
Row
(
children:
children
)
)
)
);
}
}
packages/flutter/lib/src/material/list_tile.dart
View file @
606f5622
...
@@ -5,8 +5,11 @@
...
@@ -5,8 +5,11 @@
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'colors.dart'
;
import
'constants.dart'
;
import
'constants.dart'
;
import
'debug.dart'
;
import
'debug.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'ink_well.dart'
;
import
'ink_well.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
...
@@ -28,7 +31,20 @@ enum MaterialListType {
...
@@ -28,7 +31,20 @@ enum MaterialListType {
twoLine
,
twoLine
,
/// A list tile that contains three lines of text.
/// A list tile that contains three lines of text.
threeLine
threeLine
,
}
/// Defines the title font used for [ListTile] descendants of a [ListTileTheme].
///
/// List tiles that appear in a [Drawer] use the theme's [TextTheme.body2]
/// text style, which is a little smaller than the theme's [TextTheme.subhead]
/// text style, which is used by default.
enum
ListTileStyle
{
// Use a title font that's appropriate for a [ListTile] in a list.
list
,
// Use a title font that's appropriate for a [ListTile] that appears in a [Drawer].
drawer
,
}
}
/// The vertical extent of the different types of material list tiles.
/// The vertical extent of the different types of material list tiles.
...
@@ -46,6 +62,64 @@ Map<MaterialListType, double> kListTileExtent = const <MaterialListType, double>
...
@@ -46,6 +62,64 @@ Map<MaterialListType, double> kListTileExtent = const <MaterialListType, double>
MaterialListType
.
threeLine
:
88.0
,
MaterialListType
.
threeLine
:
88.0
,
};
};
/// An inherited widget that defines color and style parameters for [ListTile]s
/// in this widget's subtree.
///
/// Values specified here are used for [ListTile] properties that are not given
/// an explicit non-null value.
///
/// The [Drawer] widget specifies a tile theme for its children which sets
/// [style] to [ListTileStyle.drawer].
class
ListTileTheme
extends
InheritedWidget
{
/// Creates an inherited widget that defines color and style parameters for [ListTile]s.
const
ListTileTheme
({
Key
key
,
this
.
dense
:
false
,
this
.
style
:
ListTileStyle
.
list
,
this
.
selectedColor
,
this
.
iconColor
,
this
.
textColor
,
Widget
child
,
})
:
super
(
key:
key
,
child:
child
);
/// If true then [ListTile]s will have the vertically dense layout.
final
bool
dense
;
/// If specified, [style] defines the font used for [ListTile] titles.
final
ListTileStyle
style
;
/// If specified, the color used for icons and text when a [ListTile] is selected.
final
Color
selectedColor
;
/// If specified, the icon color used for enabled [ListTile]s that are not selected.
final
Color
iconColor
;
/// If specified, the text color used for enabled [ListTile]s that are not selected.
final
Color
textColor
;
/// The closest instance of this class that encloses the given context.
///
/// Typical usage is as follows:
///
/// ```dart
/// ListTileTheme theme = ListTileTheme.of(context);
/// ```
static
ListTileTheme
of
(
BuildContext
context
)
{
final
ListTileTheme
result
=
context
.
inheritFromWidgetOfExactType
(
ListTileTheme
);
return
result
??
new
ListTileTheme
();
}
@override
bool
updateShouldNotify
(
ListTileTheme
oldTheme
)
{
return
dense
!=
oldTheme
.
dense
||
style
!=
oldTheme
.
style
||
selectedColor
!=
oldTheme
.
selectedColor
||
iconColor
!=
oldTheme
.
iconColor
||
textColor
!=
oldTheme
.
textColor
;
}
}
/// A single fixed-height row that typically contains some text as well as
/// A single fixed-height row that typically contains some text as well as
/// a leading or trailing icon.
/// a leading or trailing icon.
///
///
...
@@ -69,14 +143,15 @@ Map<MaterialListType, double> kListTileExtent = const <MaterialListType, double>
...
@@ -69,14 +143,15 @@ Map<MaterialListType, double> kListTileExtent = const <MaterialListType, double>
///
///
/// See also:
/// See also:
///
///
/// * [
kListTileExtent], which defines the ListTile size
s.
/// * [
ListTileTheme], which defines visual properties for [ListTile]
s.
/// * [ListView], which can display an arbitrary number of [ListTile]s
/// * [ListView], which can display an arbitrary number of [ListTile]s
/// in a scrolling list.
/// in a scrolling list.
/// * [Card], which can be used with [Column] to show a few [ListTile]s.
/// * [CircleAvatar], which shows an icon representing a person and is often
/// * [CircleAvatar], which shows an icon representing a person and is often
/// used as the [leading] element of a ListTile.
/// used as the [leading] element of a ListTile.
/// * [Card], which can be used with [Column] to show a few [ListTile]s.
/// * [Divider], which can be used to separate [ListTile]s.
/// * [Divider], which can be used to separate [ListTile]s.
/// * [ListTile.divideTiles], a utility for inserting [Divider]s in between [ListTile]s.
/// * [ListTile.divideTiles], a utility for inserting [Divider]s in between [ListTile]s.
/// * [kListTileExtent], which defines the ListTile sizes.
/// * <https://material.google.com/components/lists.html>
/// * <https://material.google.com/components/lists.html>
class
ListTile
extends
StatelessWidget
{
class
ListTile
extends
StatelessWidget
{
/// Creates a list tile.
/// Creates a list tile.
...
@@ -91,15 +166,20 @@ class ListTile extends StatelessWidget {
...
@@ -91,15 +166,20 @@ class ListTile extends StatelessWidget {
this
.
subtitle
,
this
.
subtitle
,
this
.
trailing
,
this
.
trailing
,
this
.
isThreeLine
:
false
,
this
.
isThreeLine
:
false
,
this
.
dense
:
false
,
this
.
dense
,
this
.
enabled
:
true
,
this
.
enabled
:
true
,
this
.
onTap
,
this
.
onTap
,
this
.
onLongPress
this
.
onLongPress
,
})
:
super
(
key:
key
);
this
.
selected
:
false
,
})
:
super
(
key:
key
)
{
assert
(
isThreeLine
!=
null
);
assert
(
enabled
!=
null
);
assert
(
selected
!=
null
);
}
/// A widget to display before the title.
/// A widget to display before the title.
///
///
/// Typically a [CircleAvatar] widget.
/// Typically a
n [Icon] or a
[CircleAvatar] widget.
final
Widget
leading
;
final
Widget
leading
;
/// The primary content of the list tile.
/// The primary content of the list tile.
...
@@ -124,6 +204,8 @@ class ListTile extends StatelessWidget {
...
@@ -124,6 +204,8 @@ class ListTile extends StatelessWidget {
final
bool
isThreeLine
;
final
bool
isThreeLine
;
/// Whether this list tile is part of a vertically dense list.
/// Whether this list tile is part of a vertically dense list.
///
/// If this property is null then its value is based on [ListTileTheme.dense].
final
bool
dense
;
final
bool
dense
;
/// Whether this list tile is interactive.
/// Whether this list tile is interactive.
...
@@ -143,6 +225,12 @@ class ListTile extends StatelessWidget {
...
@@ -143,6 +225,12 @@ class ListTile extends StatelessWidget {
/// Inoperative if [enabled] is false.
/// Inoperative if [enabled] is false.
final
GestureLongPressCallback
onLongPress
;
final
GestureLongPressCallback
onLongPress
;
/// If this tile is also [enabled] then icons and text are rendered with the same color.
///
/// By default the selected color is the theme's primary color. The selected color
/// can be overridden with a [ListTileTheme].
final
bool
selected
;
/// Add a one pixel border in between each tile. If color isn't specified the
/// Add a one pixel border in between each tile. If color isn't specified the
/// [ThemeData.dividerColor] of the context's [Theme] is used.
/// [ThemeData.dividerColor] of the context's [Theme] is used.
///
///
...
@@ -174,50 +262,103 @@ class ListTile extends StatelessWidget {
...
@@ -174,50 +262,103 @@ class ListTile extends StatelessWidget {
yield
tile
;
yield
tile
;
}
}
TextStyle
_primaryTextStyle
(
BuildContext
context
)
{
Color
_iconColor
(
ThemeData
theme
,
ListTileTheme
tileTheme
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
if
(!
enabled
)
final
TextStyle
style
=
theme
.
textTheme
.
subhead
;
return
theme
.
disabledColor
;
if
(!
enabled
)
{
final
Color
color
=
theme
.
disabledColor
;
if
(
selected
&&
tileTheme
?.
selectedColor
!=
null
)
return
dense
?
style
.
copyWith
(
fontSize:
13.0
,
color:
color
)
:
style
.
copyWith
(
color:
color
);
return
tileTheme
.
selectedColor
;
if
(!
selected
&&
tileTheme
?.
iconColor
!=
null
)
return
tileTheme
.
iconColor
;
switch
(
theme
.
brightness
)
{
case
Brightness
.
light
:
return
selected
?
theme
.
primaryColor
:
Colors
.
black45
;
case
Brightness
.
dark
:
return
selected
?
theme
.
accentColor
:
null
;
// null - use current icon theme color
}
}
return
dense
?
style
.
copyWith
(
fontSize:
13.0
)
:
style
;
assert
(
theme
.
brightness
!=
null
);
return
null
;
}
}
TextStyle
_secondaryTextStyle
(
BuildContext
context
)
{
Color
_textColor
(
ThemeData
theme
,
ListTileTheme
tileTheme
,
Color
defaultColor
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
if
(!
enabled
)
final
Color
color
=
theme
.
textTheme
.
caption
.
color
;
return
theme
.
disabledColor
;
if
(
selected
&&
tileTheme
?.
selectedColor
!=
null
)
return
tileTheme
.
selectedColor
;
if
(!
selected
&&
tileTheme
?.
textColor
!=
null
)
return
tileTheme
.
textColor
;
if
(
selected
)
{
switch
(
theme
.
brightness
)
{
case
Brightness
.
light
:
return
theme
.
primaryColor
;
case
Brightness
.
dark
:
return
theme
.
accentColor
;
}
}
return
defaultColor
;
}
bool
_denseLayout
(
ListTileTheme
tileTheme
)
{
return
dense
!=
null
?
dense
:
(
tileTheme
?.
dense
??
false
);
}
TextStyle
_titleTextStyle
(
ThemeData
theme
,
ListTileTheme
tileTheme
)
{
final
TextStyle
style
=
tileTheme
?.
style
==
ListTileStyle
.
drawer
?
theme
.
textTheme
.
body2
:
theme
.
textTheme
.
subhead
;
final
Color
color
=
_textColor
(
theme
,
tileTheme
,
style
.
color
);
return
_denseLayout
(
tileTheme
)
?
style
.
copyWith
(
fontSize:
13.0
,
color:
color
)
:
style
.
copyWith
(
color:
color
);
}
TextStyle
_subtitleTextStyle
(
ThemeData
theme
,
ListTileTheme
tileTheme
)
{
final
TextStyle
style
=
theme
.
textTheme
.
body1
;
final
TextStyle
style
=
theme
.
textTheme
.
body1
;
return
dense
?
style
.
copyWith
(
color:
color
,
fontSize:
12.0
)
:
style
.
copyWith
(
color:
color
);
final
Color
color
=
_textColor
(
theme
,
tileTheme
,
theme
.
textTheme
.
caption
.
color
);
return
_denseLayout
(
tileTheme
)
?
style
.
copyWith
(
color:
color
,
fontSize:
12.0
)
:
style
.
copyWith
(
color:
color
);
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
assert
(
debugCheckHasMaterial
(
context
));
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ListTileTheme
tileTheme
=
ListTileTheme
.
of
(
context
);
final
bool
isTwoLine
=
!
isThreeLine
&&
subtitle
!=
null
;
final
bool
isTwoLine
=
!
isThreeLine
&&
subtitle
!=
null
;
final
bool
isOneLine
=
!
isThreeLine
&&
!
isTwoLine
;
final
bool
isOneLine
=
!
isThreeLine
&&
!
isTwoLine
;
double
tileHeight
;
double
tileHeight
;
if
(
isOneLine
)
if
(
isOneLine
)
tileHeight
=
dense
?
48.0
:
56.0
;
tileHeight
=
_denseLayout
(
tileTheme
)
?
48.0
:
56.0
;
else
if
(
isTwoLine
)
else
if
(
isTwoLine
)
tileHeight
=
dense
?
60.0
:
72.0
;
tileHeight
=
_denseLayout
(
tileTheme
)
?
60.0
:
72.0
;
else
else
tileHeight
=
dense
?
76.0
:
88.0
;
tileHeight
=
_denseLayout
(
tileTheme
)
?
76.0
:
88.0
;
// Overall, the list tile is a Row() with these children.
// Overall, the list tile is a Row() with these children.
final
List
<
Widget
>
children
=
<
Widget
>[];
final
List
<
Widget
>
children
=
<
Widget
>[];
if
(
leading
!=
null
)
{
if
(
leading
!=
null
)
{
children
.
add
(
new
Container
(
children
.
add
(
new
IconTheme
.
merge
(
margin:
const
EdgeInsets
.
only
(
right:
16.0
),
context:
context
,
width:
40.0
,
data:
new
IconThemeData
(
color:
_iconColor
(
theme
,
tileTheme
)),
alignment:
FractionalOffset
.
centerLeft
,
child:
new
Container
(
child:
leading
margin:
const
EdgeInsets
.
only
(
right:
16.0
),
width:
40.0
,
alignment:
FractionalOffset
.
centerLeft
,
child:
leading
),
));
));
}
}
final
Widget
primaryLine
=
new
AnimatedDefaultTextStyle
(
final
Widget
primaryLine
=
new
AnimatedDefaultTextStyle
(
style:
_
primaryTextStyle
(
context
),
style:
_
titleTextStyle
(
theme
,
tileTheme
),
duration:
kThemeChangeDuration
,
duration:
kThemeChangeDuration
,
child:
title
??
new
Container
()
child:
title
??
new
Container
()
);
);
...
@@ -229,22 +370,22 @@ class ListTile extends StatelessWidget {
...
@@ -229,22 +370,22 @@ class ListTile extends StatelessWidget {
children:
<
Widget
>[
children:
<
Widget
>[
primaryLine
,
primaryLine
,
new
AnimatedDefaultTextStyle
(
new
AnimatedDefaultTextStyle
(
style:
_s
econdaryTextStyle
(
context
),
style:
_s
ubtitleTextStyle
(
theme
,
tileTheme
),
duration:
kThemeChangeDuration
,
duration:
kThemeChangeDuration
,
child:
subtitle
child:
subtitle
,
)
)
]
]
);
);
}
}
children
.
add
(
new
Expanded
(
children
.
add
(
new
Expanded
(
child:
center
child:
center
,
));
));
if
(
trailing
!=
null
)
{
if
(
trailing
!=
null
)
{
children
.
add
(
new
Container
(
children
.
add
(
new
Container
(
margin:
const
EdgeInsets
.
only
(
left:
16.0
),
margin:
const
EdgeInsets
.
only
(
left:
16.0
),
alignment:
FractionalOffset
.
centerRight
,
alignment:
FractionalOffset
.
centerRight
,
child:
trailing
child:
trailing
,
));
));
}
}
...
@@ -254,9 +395,7 @@ class ListTile extends StatelessWidget {
...
@@ -254,9 +395,7 @@ class ListTile extends StatelessWidget {
child:
new
Container
(
child:
new
Container
(
height:
tileHeight
,
height:
tileHeight
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
child:
new
Row
(
child:
new
Row
(
children:
children
),
children:
children
)
)
)
);
);
}
}
...
...
packages/flutter/test/material/about_test.dart
View file @
606f5622
...
@@ -9,7 +9,7 @@ import 'package:flutter/material.dart';
...
@@ -9,7 +9,7 @@ import 'package:flutter/material.dart';
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
void
main
(
)
{
testWidgets
(
'About
DrawerItem
control test'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'About
ListTile
control test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
new
MaterialApp
(
new
MaterialApp
(
title:
'Pirate app'
,
title:
'Pirate app'
,
...
@@ -20,7 +20,7 @@ void main() {
...
@@ -20,7 +20,7 @@ void main() {
drawer:
new
Drawer
(
drawer:
new
Drawer
(
child:
new
ListView
(
child:
new
ListView
(
children:
<
Widget
>[
children:
<
Widget
>[
new
About
DrawerItem
(
new
About
ListTile
(
applicationVersion:
'0.1.2'
,
applicationVersion:
'0.1.2'
,
applicationIcon:
const
FlutterLogo
(),
applicationIcon:
const
FlutterLogo
(),
applicationLegalese:
'I am the very model of a modern major general.'
,
applicationLegalese:
'I am the very model of a modern major general.'
,
...
@@ -67,12 +67,12 @@ void main() {
...
@@ -67,12 +67,12 @@ void main() {
testWidgets
(
'About box logic defaults to executable name for app name'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'About box logic defaults to executable name for app name'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
new
Material
(
child:
new
About
DrawerItem
()),
new
Material
(
child:
new
About
ListTile
()),
);
);
expect
(
find
.
text
(
'About sky_shell'
),
findsOneWidget
);
expect
(
find
.
text
(
'About sky_shell'
),
findsOneWidget
);
});
});
testWidgets
(
'About
DrawerItem
control test'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'About
ListTile
control test'
,
(
WidgetTester
tester
)
async
{
final
List
<
String
>
log
=
<
String
>[];
final
List
<
String
>
log
=
<
String
>[];
Future
<
Null
>
licenseFuture
;
Future
<
Null
>
licenseFuture
;
...
...
packages/flutter/test/material/drawer_test.dart
View file @
606f5622
...
@@ -20,9 +20,9 @@ void main() {
...
@@ -20,9 +20,9 @@ void main() {
child:
new
Text
(
'header'
)
child:
new
Text
(
'header'
)
)
)
),
),
new
DrawerItem
(
new
ListTile
(
icon
:
new
Icon
(
Icons
.
archive
),
leading
:
new
Icon
(
Icons
.
archive
),
child
:
new
Text
(
'Archive'
)
title
:
new
Text
(
'Archive'
)
)
)
]
]
)
)
...
...
packages/flutter/test/material/list_item_test.dart
deleted
100644 → 0
View file @
51ea62c1
// 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_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'ListTile control test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
MaterialApp
(
home:
new
Material
(
child:
new
Center
(
child:
new
ListTile
(
leading:
new
Icon
(
Icons
.
thumb_up
),
title:
new
Text
(
'Title'
),
subtitle:
new
Text
(
'Subtitle'
),
trailing:
new
Icon
(
Icons
.
info
),
enabled:
false
,
),
),
),
));
expect
(
find
.
text
(
'Title'
),
findsOneWidget
);
expect
(
find
.
text
(
'Subtitle'
),
findsOneWidget
);
});
testWidgets
(
'ListTile control test'
,
(
WidgetTester
tester
)
async
{
final
List
<
String
>
titles
=
<
String
>[
'first'
,
'second'
,
'third'
];
await
tester
.
pumpWidget
(
new
MaterialApp
(
home:
new
Material
(
child:
new
Builder
(
builder:
(
BuildContext
context
)
{
return
new
ListView
(
children:
ListTile
.
divideTiles
(
context:
context
,
tiles:
titles
.
map
((
String
title
)
=>
new
ListTile
(
title:
new
Text
(
title
))),
).
toList
(),
);
},
),
),
));
expect
(
find
.
text
(
'first'
),
findsOneWidget
);
expect
(
find
.
text
(
'second'
),
findsOneWidget
);
expect
(
find
.
text
(
'third'
),
findsOneWidget
);
});
}
packages/flutter/test/material/list_tile_test.dart
0 → 100644
View file @
606f5622
// 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_test/flutter_test.dart'
;
class
TestIcon
extends
StatefulWidget
{
TestIcon
({
Key
key
})
:
super
(
key:
key
);
@override
TestIconState
createState
()
=>
new
TestIconState
();
}
class
TestIconState
extends
State
<
TestIcon
>
{
IconThemeData
iconTheme
;
@override
Widget
build
(
BuildContext
context
)
{
iconTheme
=
IconTheme
.
of
(
context
);
return
new
Icon
(
Icons
.
add
);
}
}
class
TestText
extends
StatefulWidget
{
TestText
(
this
.
text
,
{
Key
key
})
:
super
(
key:
key
);
final
String
text
;
@override
TestTextState
createState
()
=>
new
TestTextState
();
}
class
TestTextState
extends
State
<
TestText
>
{
TextStyle
textStyle
;
@override
Widget
build
(
BuildContext
context
)
{
textStyle
=
DefaultTextStyle
.
of
(
context
).
style
;
return
new
Text
(
config
.
text
);
}
}
void
main
(
)
{
testWidgets
(
'ListTile geometry'
,
(
WidgetTester
tester
)
async
{
// See https://material.io/guidelines/components/lists.html
bool
hasSubtitle
;
Widget
buildFrame
({
bool
dense:
false
,
bool
isTwoLine:
false
,
bool
isThreeLine:
false
})
{
hasSubtitle
=
isTwoLine
||
isThreeLine
;
return
new
MaterialApp
(
home:
new
Material
(
child:
new
Center
(
child:
new
ListTile
(
leading:
new
Text
(
'leading'
),
title:
new
Text
(
'title'
),
subtitle:
hasSubtitle
?
new
Text
(
'subtitle'
)
:
null
,
trailing:
new
Text
(
'trailing'
),
dense:
dense
,
isThreeLine:
isThreeLine
,
),
),
),
);
}
void
testChildren
()
{
expect
(
find
.
text
(
'leading'
),
findsOneWidget
);
expect
(
find
.
text
(
'title'
),
findsOneWidget
);
if
(
hasSubtitle
)
expect
(
find
.
text
(
'subtitle'
),
findsOneWidget
);
expect
(
find
.
text
(
'trailing'
),
findsOneWidget
);
}
double
left
(
String
text
)
=>
tester
.
getTopLeft
(
find
.
text
(
text
)).
x
;
double
right
(
String
text
)
=>
tester
.
getTopRight
(
find
.
text
(
text
)).
x
;
double
top
(
String
text
)
=>
tester
.
getTopLeft
(
find
.
text
(
text
)).
y
;
double
bottom
(
String
text
)
=>
tester
.
getBottomLeft
(
find
.
text
(
text
)).
y
;
// 16.0 padding to the left and right of the leading and trailing widgets
void
testHorizontalGeometry
()
{
expect
(
left
(
'leading'
),
16.0
);
expect
(
left
(
'title'
),
72.0
);
if
(
hasSubtitle
)
expect
(
left
(
'subtitle'
),
72.0
);
expect
(
left
(
'title'
),
right
(
'leading'
)
+
16.0
);
expect
(
right
(
'trailing'
),
800.0
-
16.0
);
}
void
testVerticalGeometry
(
double
expectedHeight
)
{
expect
(
tester
.
getSize
(
find
.
byType
(
ListTile
)),
new
Size
(
800.0
,
expectedHeight
));
if
(
hasSubtitle
)
expect
(
top
(
'subtitle'
),
bottom
(
'title'
));
}
await
tester
.
pumpWidget
(
buildFrame
());
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
56.0
);
await
tester
.
pumpWidget
(
buildFrame
(
dense:
true
));
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
48.0
);
await
tester
.
pumpWidget
(
buildFrame
(
isTwoLine:
true
));
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
72.0
);
await
tester
.
pumpWidget
(
buildFrame
(
isTwoLine:
true
,
dense:
true
));
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
60.0
);
await
tester
.
pumpWidget
(
buildFrame
(
isThreeLine:
true
));
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
88.0
);
await
tester
.
pumpWidget
(
buildFrame
(
isThreeLine:
true
,
dense:
true
));
testChildren
();
testHorizontalGeometry
();
testVerticalGeometry
(
76.0
);
});
testWidgets
(
'ListTile.divideTiles'
,
(
WidgetTester
tester
)
async
{
final
List
<
String
>
titles
=
<
String
>[
'first'
,
'second'
,
'third'
];
await
tester
.
pumpWidget
(
new
MaterialApp
(
home:
new
Material
(
child:
new
Builder
(
builder:
(
BuildContext
context
)
{
return
new
ListView
(
children:
ListTile
.
divideTiles
(
context:
context
,
tiles:
titles
.
map
((
String
title
)
=>
new
ListTile
(
title:
new
Text
(
title
))),
).
toList
(),
);
},
),
),
));
expect
(
find
.
text
(
'first'
),
findsOneWidget
);
expect
(
find
.
text
(
'second'
),
findsOneWidget
);
expect
(
find
.
text
(
'third'
),
findsOneWidget
);
});
testWidgets
(
'ListTileTheme'
,
(
WidgetTester
tester
)
async
{
final
Key
titleKey
=
new
UniqueKey
();
final
Key
subtitleKey
=
new
UniqueKey
();
ThemeData
theme
;
Widget
buildFrame
({
bool
enabled:
true
,
bool
dense:
false
,
bool
selected:
false
,
Color
selectedColor
,
Color
iconColor
,
Color
textColor
,
})
{
return
new
MaterialApp
(
home:
new
Material
(
child:
new
Center
(
child:
new
ListTileTheme
(
dense:
dense
,
selectedColor:
selectedColor
,
iconColor:
iconColor
,
textColor:
textColor
,
child:
new
Builder
(
builder:
(
BuildContext
context
)
{
theme
=
Theme
.
of
(
context
);
return
new
ListTile
(
enabled:
enabled
,
selected:
selected
,
leading:
new
TestIcon
(),
title:
new
TestText
(
'title'
,
key:
titleKey
),
subtitle:
new
TestText
(
'subtitle'
,
key:
subtitleKey
),
);
}
),
),
),
),
);
}
const
Color
green
=
const
Color
(
0xFF00FF00
);
const
Color
red
=
const
Color
(
0xFFFF0000
);
Color
iconColor
()
=>
tester
.
state
<
TestIconState
>(
find
.
byType
(
TestIcon
)).
iconTheme
.
color
;
Color
textColor
(
Key
key
)
=>
tester
.
state
<
TestTextState
>(
find
.
byKey
(
key
)).
textStyle
.
color
;
// A selected ListTile's leading and text get the primary color by default
await
(
tester
.
pumpWidget
(
buildFrame
(
selected:
true
)));
await
(
tester
.
pump
(
const
Duration
(
milliseconds:
300
)));
// DefaultTextStyle changes animate
expect
(
iconColor
(),
theme
.
primaryColor
);
expect
(
textColor
(
titleKey
),
theme
.
primaryColor
);
expect
(
textColor
(
subtitleKey
),
theme
.
primaryColor
);
// A selected ListTile's leading and text get the ListTileTheme's selectedColor
await
(
tester
.
pumpWidget
(
buildFrame
(
selected:
true
,
selectedColor:
green
)));
await
(
tester
.
pump
(
const
Duration
(
milliseconds:
300
)));
// DefaultTextStyle changes animate
expect
(
iconColor
(),
green
);
expect
(
textColor
(
titleKey
),
green
);
expect
(
textColor
(
subtitleKey
),
green
);
// An unselected ListTile's leading icon gets the ListTileTheme's iconColor
// An unselected ListTile's title texts get the ListTileTheme's textColor
await
(
tester
.
pumpWidget
(
buildFrame
(
iconColor:
red
,
textColor:
green
)));
await
(
tester
.
pump
(
const
Duration
(
milliseconds:
300
)));
// DefaultTextStyle changes animate
expect
(
iconColor
(),
red
);
expect
(
textColor
(
titleKey
),
green
);
expect
(
textColor
(
subtitleKey
),
green
);
// If the item is disabled it's rendered with the theme's disabled color.
await
(
tester
.
pumpWidget
(
buildFrame
(
enabled:
false
)));
await
(
tester
.
pump
(
const
Duration
(
milliseconds:
300
)));
// DefaultTextStyle changes animate
expect
(
iconColor
(),
theme
.
disabledColor
);
expect
(
textColor
(
titleKey
),
theme
.
disabledColor
);
expect
(
textColor
(
subtitleKey
),
theme
.
disabledColor
);
// If the item is disabled it's rendered with the theme's disabled color.
// Even if it's selected.
await
(
tester
.
pumpWidget
(
buildFrame
(
enabled:
false
,
selected:
true
)));
await
(
tester
.
pump
(
const
Duration
(
milliseconds:
300
)));
// DefaultTextStyle changes animate
expect
(
iconColor
(),
theme
.
disabledColor
);
expect
(
textColor
(
titleKey
),
theme
.
disabledColor
);
expect
(
textColor
(
subtitleKey
),
theme
.
disabledColor
);
});
}
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