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
cf12c314
Unverified
Commit
cf12c314
authored
Mar 20, 2019
by
Shi-Hao Hong
Committed by
GitHub
Mar 20, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DropdownButton Icon customizability (#29572)
parent
8da07214
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
197 additions
and
12 deletions
+197
-12
dropdown.dart
packages/flutter/lib/src/material/dropdown.dart
+54
-12
dropdown_test.dart
packages/flutter/test/material/dropdown_test.dart
+143
-0
No files found.
packages/flutter/lib/src/material/dropdown.dart
View file @
cf12c314
...
...
@@ -599,6 +599,9 @@ class DropdownButton<T> extends StatefulWidget {
@required
this
.
onChanged
,
this
.
elevation
=
8
,
this
.
style
,
this
.
icon
,
this
.
iconDisabledColor
,
this
.
iconEnabledColor
,
this
.
iconSize
=
24.0
,
this
.
isDense
=
false
,
this
.
isExpanded
=
false
,
...
...
@@ -653,6 +656,27 @@ class DropdownButton<T> extends StatefulWidget {
/// [ThemeData.textTheme] of the current [Theme].
final
TextStyle
style
;
/// The widget to use for the drop-down button's icon.
///
/// Defaults to an [Icon] with the [Icons.arrow_drop_down] glyph.
final
Widget
icon
;
/// The color of any [Icon] descendant of [icon] if this button is disabled,
/// i.e. if [onChanged] is null.
///
/// Defaults to [Colors.grey.shade400] when the theme's
/// [ThemeData.brightness] is [Brightness.light] and to
/// [Colors.white10] when it is [Brightness.dark]
final
Color
iconDisabledColor
;
/// The color of any [Icon] descendant of [icon] if this button is enabled,
/// i.e. if [onChanged] is defined.
///
/// Defaults to [Colors.grey.shade700] when the theme's
/// [ThemeData.brightness] is [Brightness.light] and to
/// [Colors.white70] when it is [Brightness.dark]
final
Color
iconEnabledColor
;
/// The size to use for the drop-down button's down arrow icon button.
///
/// Defaults to 24.0.
...
...
@@ -768,21 +792,34 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
return
math
.
max
(
_textStyle
.
fontSize
,
math
.
max
(
widget
.
iconSize
,
_kDenseButtonHeight
));
}
Color
get
_
downArrow
Color
{
Color
get
_
icon
Color
{
// These colors are not defined in the Material Design spec.
if
(
_enabled
)
{
if
(
Theme
.
of
(
context
).
brightness
==
Brightness
.
light
)
{
if
(
widget
.
iconEnabledColor
!=
null
)
{
return
widget
.
iconEnabledColor
;
}
switch
(
Theme
.
of
(
context
).
brightness
)
{
case
Brightness
.
light
:
return
Colors
.
grey
.
shade700
;
}
else
{
case
Brightness
.
dark
:
return
Colors
.
white70
;
}
}
else
{
if
(
Theme
.
of
(
context
).
brightness
==
Brightness
.
light
)
{
if
(
widget
.
iconDisabledColor
!=
null
)
{
return
widget
.
iconDisabledColor
;
}
switch
(
Theme
.
of
(
context
).
brightness
)
{
case
Brightness
.
light
:
return
Colors
.
grey
.
shade400
;
}
else
{
case
Brightness
.
dark
:
return
Colors
.
white10
;
}
}
assert
(
false
);
return
null
;
}
bool
get
_enabled
=>
widget
.
items
!=
null
&&
widget
.
items
.
isNotEmpty
&&
widget
.
onChanged
!=
null
;
...
...
@@ -827,6 +864,8 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
);
}
const
Icon
defaultIcon
=
Icon
(
Icons
.
arrow_drop_down
);
Widget
result
=
DefaultTextStyle
(
style:
_textStyle
,
child:
Container
(
...
...
@@ -837,9 +876,12 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
widget
.
isExpanded
?
Expanded
(
child:
innerItemsWidget
)
:
innerItemsWidget
,
Icon
(
Icons
.
arrow_drop_down
,
IconTheme
(
data:
IconThemeData
(
color:
_iconColor
,
size:
widget
.
iconSize
,
color:
_downArrowColor
,
),
child:
widget
.
icon
??
defaultIcon
,
),
],
),
...
...
packages/flutter/test/material/dropdown_test.dart
View file @
cf12c314
...
...
@@ -20,10 +20,21 @@ final Type dropdownButtonType = DropdownButton<String>(
items:
const
<
DropdownMenuItem
<
String
>>[],
).
runtimeType
;
Finder
_iconRichText
(
Key
iconKey
)
{
return
find
.
descendant
(
of:
find
.
byKey
(
iconKey
),
matching:
find
.
byType
(
RichText
),
);
}
Widget
buildFrame
(
{
Key
buttonKey
,
String
value
=
'two'
,
ValueChanged
<
String
>
onChanged
,
Widget
icon
,
Color
iconDisabledColor
,
Color
iconEnabledColor
,
double
iconSize
=
24.0
,
bool
isDense
=
false
,
bool
isExpanded
=
false
,
Widget
hint
,
...
...
@@ -44,6 +55,10 @@ Widget buildFrame({
hint:
hint
,
disabledHint:
disabledHint
,
onChanged:
onChanged
,
icon:
icon
,
iconSize:
iconSize
,
iconDisabledColor:
iconDisabledColor
,
iconEnabledColor:
iconEnabledColor
,
isDense:
isDense
,
isExpanded:
isExpanded
,
items:
items
==
null
?
null
:
items
.
map
<
DropdownMenuItem
<
String
>>((
String
item
)
{
...
...
@@ -430,6 +445,134 @@ void main() {
buttonBox
.
size
.
centerRight
(
Offset
(-
arrowIcon
.
size
.
width
,
0.0
)).
dx
);
});
testWidgets
(
'Dropdown button icon will accept widgets as icons'
,
(
WidgetTester
tester
)
async
{
final
Widget
customWidget
=
Container
(
decoration:
ShapeDecoration
(
shape:
CircleBorder
(
side:
BorderSide
(
width:
5.0
,
color:
Colors
.
grey
.
shade700
,
),
),
),
);
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customWidget
,
onChanged:
onChanged
,
));
expect
(
find
.
byWidget
(
customWidget
),
findsOneWidget
);
expect
(
find
.
byIcon
(
Icons
.
arrow_drop_down
),
findsNothing
);
await
tester
.
pumpWidget
(
buildFrame
(
icon:
const
Icon
(
Icons
.
assessment
),
onChanged:
onChanged
,
));
expect
(
find
.
byIcon
(
Icons
.
assessment
),
findsOneWidget
);
expect
(
find
.
byIcon
(
Icons
.
arrow_drop_down
),
findsNothing
);
});
testWidgets
(
'Dropdown button icon should have default size and colors when not defined'
,
(
WidgetTester
tester
)
async
{
final
Key
iconKey
=
UniqueKey
();
final
Icon
customIcon
=
Icon
(
Icons
.
assessment
,
key:
iconKey
);
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
onChanged:
onChanged
,
));
// test for size
final
RenderBox
icon
=
tester
.
renderObject
(
find
.
byKey
(
iconKey
));
expect
(
icon
.
size
,
const
Size
(
24.0
,
24.0
));
// test for enabled color
final
RichText
enabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
enabledRichText
.
text
.
style
.
color
,
Colors
.
grey
.
shade700
);
// test for disabled color
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
onChanged:
null
,
));
final
RichText
disabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
disabledRichText
.
text
.
style
.
color
,
Colors
.
grey
.
shade400
);
});
testWidgets
(
'Dropdown button icon should have the passed in size and color instead of defaults'
,
(
WidgetTester
tester
)
async
{
final
Key
iconKey
=
UniqueKey
();
final
Icon
customIcon
=
Icon
(
Icons
.
assessment
,
key:
iconKey
);
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
iconSize:
30.0
,
iconEnabledColor:
Colors
.
pink
,
iconDisabledColor:
Colors
.
orange
,
onChanged:
onChanged
,
));
// test for size
final
RenderBox
icon
=
tester
.
renderObject
(
find
.
byKey
(
iconKey
));
expect
(
icon
.
size
,
const
Size
(
30.0
,
30.0
));
// test for enabled color
final
RichText
enabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
enabledRichText
.
text
.
style
.
color
,
Colors
.
pink
);
// test for disabled color
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
iconSize:
30.0
,
iconEnabledColor:
Colors
.
pink
,
iconDisabledColor:
Colors
.
orange
,
onChanged:
null
,
));
final
RichText
disabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
disabledRichText
.
text
.
style
.
color
,
Colors
.
orange
);
});
testWidgets
(
'Dropdown button should use its own size and color properties over those defined by the theme'
,
(
WidgetTester
tester
)
async
{
final
Key
iconKey
=
UniqueKey
();
final
Icon
customIcon
=
Icon
(
Icons
.
assessment
,
key:
iconKey
,
size:
40.0
,
color:
Colors
.
yellow
,
);
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
iconSize:
30.0
,
iconEnabledColor:
Colors
.
pink
,
iconDisabledColor:
Colors
.
orange
,
onChanged:
onChanged
,
));
// test for size
final
RenderBox
icon
=
tester
.
renderObject
(
find
.
byKey
(
iconKey
));
expect
(
icon
.
size
,
const
Size
(
40.0
,
40.0
));
// test for enabled color
final
RichText
enabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
enabledRichText
.
text
.
style
.
color
,
Colors
.
yellow
);
// test for disabled color
await
tester
.
pumpWidget
(
buildFrame
(
icon:
customIcon
,
iconSize:
30.0
,
iconEnabledColor:
Colors
.
pink
,
iconDisabledColor:
Colors
.
orange
,
onChanged:
null
,
));
final
RichText
disabledRichText
=
tester
.
widget
<
RichText
>(
_iconRichText
(
iconKey
));
expect
(
disabledRichText
.
text
.
style
.
color
,
Colors
.
yellow
);
});
testWidgets
(
'Dropdown button with isDense:true aligns selected menu item'
,
(
WidgetTester
tester
)
async
{
final
Key
buttonKey
=
UniqueKey
();
const
String
value
=
'two'
;
...
...
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