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
2977a346
Unverified
Commit
2977a346
authored
Mar 22, 2021
by
Shi-Hao Hong
Committed by
GitHub
Mar 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Custom PopupMenuItem padding (#78523)
parent
c0bcb4fc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
233 additions
and
6 deletions
+233
-6
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+20
-6
popup_menu_test.dart
packages/flutter/test/material/popup_menu_test.dart
+213
-0
No files found.
packages/flutter/lib/src/material/popup_menu.dart
View file @
2977a346
...
...
@@ -221,6 +221,7 @@ class PopupMenuItem<T> extends PopupMenuEntry<T> {
this
.
value
,
this
.
enabled
=
true
,
this
.
height
=
kMinInteractiveDimension
,
this
.
padding
,
this
.
textStyle
,
this
.
mouseCursor
,
required
this
.
child
,
...
...
@@ -243,6 +244,15 @@ class PopupMenuItem<T> extends PopupMenuEntry<T> {
@override
final
double
height
;
/// The padding of the menu item.
///
/// Note that [height] may interact with the applied padding. For example,
/// If a [height] greater than the height of the sum of the padding and [child]
/// is provided, then the padding's effect will not be visible.
///
/// When null, the horizontal padding defaults to 16.0 on both sides.
final
EdgeInsets
?
padding
;
/// The text style of the popup menu item.
///
/// If this property is null, then [PopupMenuThemeData.textStyle] is used.
...
...
@@ -327,7 +337,7 @@ class PopupMenuItemState<T, W extends PopupMenuItem<T>> extends State<W> {
child:
Container
(
alignment:
AlignmentDirectional
.
centerStart
,
constraints:
BoxConstraints
(
minHeight:
widget
.
height
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
_kMenuHorizontalPadding
),
padding:
widget
.
padding
??
const
EdgeInsets
.
symmetric
(
horizontal:
_kMenuHorizontalPadding
),
child:
buildChild
(),
),
);
...
...
@@ -435,14 +445,18 @@ class CheckedPopupMenuItem<T> extends PopupMenuItem<T> {
T
?
value
,
this
.
checked
=
false
,
bool
enabled
=
true
,
EdgeInsets
?
padding
,
double
height
=
kMinInteractiveDimension
,
Widget
?
child
,
})
:
assert
(
checked
!=
null
),
super
(
key:
key
,
value:
value
,
enabled:
enabled
,
child:
child
,
);
key:
key
,
value:
value
,
enabled:
enabled
,
padding:
padding
,
height:
height
,
child:
child
,
);
/// Whether to display a checkmark next to the menu item.
///
...
...
packages/flutter/test/material/popup_menu_test.dart
View file @
2977a346
...
...
@@ -1278,6 +1278,219 @@ void main() {
);
});
testWidgets
(
'PopupMenuItem custom padding'
,
(
WidgetTester
tester
)
async
{
final
Key
popupMenuButtonKey
=
UniqueKey
();
final
Type
menuItemType
=
const
PopupMenuItem
<
String
>(
child:
Text
(
'item'
)).
runtimeType
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
PopupMenuButton
<
String
>(
key:
popupMenuButtonKey
,
child:
const
Text
(
'button'
),
onSelected:
(
String
result
)
{
},
itemBuilder:
(
BuildContext
context
)
{
return
<
PopupMenuEntry
<
String
>>[
const
PopupMenuItem
<
String
>(
padding:
EdgeInsets
.
zero
,
value:
'0'
,
child:
Text
(
'Item 0'
),
),
const
PopupMenuItem
<
String
>(
padding:
EdgeInsets
.
zero
,
height:
0
,
value:
'0'
,
child:
Text
(
'Item 1'
),
),
const
PopupMenuItem
<
String
>(
padding:
EdgeInsets
.
all
(
20
),
value:
'0'
,
child:
Text
(
'Item 2'
),
),
const
PopupMenuItem
<
String
>(
padding:
EdgeInsets
.
all
(
20
),
height:
100
,
value:
'0'
,
child:
Text
(
'Item 3'
),
),
];
},
),
),
),
),
);
// Show the menu
await
tester
.
tap
(
find
.
byKey
(
popupMenuButtonKey
));
await
tester
.
pumpAndSettle
();
// The menu items and their InkWells should have the expected vertical size
// given the interactions between heights and padding.
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 0'
)).
height
,
48
);
// Minimum interactive height (48)
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 1'
)).
height
,
16
);
// Height of text (16)
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 2'
)).
height
,
56
);
// Padding (20.0 + 20.0) + Height of text (16) = 56
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 3'
)).
height
,
100
);
// Height value of 100, since child (16) + padding (40) < 100
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 0'
)).
padding
,
EdgeInsets
.
zero
);
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 1'
)).
padding
,
EdgeInsets
.
zero
);
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 2'
)).
padding
,
const
EdgeInsets
.
all
(
20
));
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 3'
)).
padding
,
const
EdgeInsets
.
all
(
20
));
});
testWidgets
(
'CheckedPopupMenuItem child height is a minimum, child is vertically centered'
,
(
WidgetTester
tester
)
async
{
final
Key
popupMenuButtonKey
=
UniqueKey
();
final
Type
menuItemType
=
const
CheckedPopupMenuItem
<
String
>(
child:
Text
(
'item'
)).
runtimeType
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
PopupMenuButton
<
String
>(
key:
popupMenuButtonKey
,
child:
const
Text
(
'button'
),
onSelected:
(
String
result
)
{
},
itemBuilder:
(
BuildContext
context
)
{
return
<
PopupMenuEntry
<
String
>>[
// This menu item's height will be 56.0 because the default minimum height
// is 48, but the contents of PopupMenuItem are 56.0 tall.
const
CheckedPopupMenuItem
<
String
>(
checked:
true
,
value:
'0'
,
child:
Text
(
'Item 0'
),
),
// This menu item's height parameter specifies its minimum height. The
// overall height of the menu item will be 60 because the child's
// height 56, is less than 60.
const
CheckedPopupMenuItem
<
String
>(
checked:
true
,
height:
60
,
value:
'1'
,
child:
SizedBox
(
height:
40
,
child:
Text
(
'Item 1'
),
),
),
// This menu item's height parameter specifies its minimum height, so the
// overall height of the menu item will be 75.
const
CheckedPopupMenuItem
<
String
>(
checked:
true
,
height:
75
,
value:
'2'
,
child:
SizedBox
(
child:
Text
(
'Item 2'
),
),
),
// This menu item's height will be 100.
const
CheckedPopupMenuItem
<
String
>(
checked:
true
,
height:
100
,
value:
'3'
,
child:
SizedBox
(
child:
Text
(
'Item 3'
),
),
),
];
},
),
),
),
),
);
// Show the menu
await
tester
.
tap
(
find
.
byKey
(
popupMenuButtonKey
));
await
tester
.
pumpAndSettle
();
// The menu items and their InkWells should have the expected vertical size
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 0'
)).
height
,
56
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 1'
)).
height
,
60
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 2'
)).
height
,
75
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 3'
)).
height
,
100
);
// We evaluate the InkWell at the first index because that is the ListTile's
// InkWell, which wins in the gesture arena over the child's InkWell and
// is the one of interest.
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
InkWell
,
'Item 0'
).
at
(
1
)).
height
,
56
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
InkWell
,
'Item 1'
).
at
(
1
)).
height
,
60
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
InkWell
,
'Item 2'
).
at
(
1
)).
height
,
75
);
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
InkWell
,
'Item 3'
).
at
(
1
)).
height
,
100
);
// Menu item children which whose height is less than the PopupMenuItem
// are vertically centered.
expect
(
tester
.
getRect
(
find
.
widgetWithText
(
menuItemType
,
'Item 0'
)).
center
.
dy
,
tester
.
getRect
(
find
.
text
(
'Item 0'
)).
center
.
dy
,
);
expect
(
tester
.
getRect
(
find
.
widgetWithText
(
menuItemType
,
'Item 2'
)).
center
.
dy
,
tester
.
getRect
(
find
.
text
(
'Item 2'
)).
center
.
dy
,
);
});
testWidgets
(
'CheckedPopupMenuItem custom padding'
,
(
WidgetTester
tester
)
async
{
final
Key
popupMenuButtonKey
=
UniqueKey
();
final
Type
menuItemType
=
const
CheckedPopupMenuItem
<
String
>(
child:
Text
(
'item'
)).
runtimeType
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
PopupMenuButton
<
String
>(
key:
popupMenuButtonKey
,
child:
const
Text
(
'button'
),
onSelected:
(
String
result
)
{
},
itemBuilder:
(
BuildContext
context
)
{
return
<
PopupMenuEntry
<
String
>>[
const
CheckedPopupMenuItem
<
String
>(
padding:
EdgeInsets
.
zero
,
value:
'0'
,
child:
Text
(
'Item 0'
),
),
const
CheckedPopupMenuItem
<
String
>(
padding:
EdgeInsets
.
zero
,
height:
0
,
value:
'0'
,
child:
Text
(
'Item 1'
),
),
const
CheckedPopupMenuItem
<
String
>(
padding:
EdgeInsets
.
all
(
20
),
value:
'0'
,
child:
Text
(
'Item 2'
),
),
const
CheckedPopupMenuItem
<
String
>(
padding:
EdgeInsets
.
all
(
20
),
height:
100
,
value:
'0'
,
child:
Text
(
'Item 3'
),
),
];
},
),
),
),
),
);
// Show the menu
await
tester
.
tap
(
find
.
byKey
(
popupMenuButtonKey
));
await
tester
.
pumpAndSettle
();
// The menu items and their InkWells should have the expected vertical size
// given the interactions between heights and padding.
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 0'
)).
height
,
56
);
// Minimum ListTile height (56)
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 1'
)).
height
,
56
);
// Minimum ListTile height (56)
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 2'
)).
height
,
96
);
// Padding (20.0 + 20.0) + Height of ListTile (56) = 96
expect
(
tester
.
getSize
(
find
.
widgetWithText
(
menuItemType
,
'Item 3'
)).
height
,
100
);
// Height value of 100, since child (56) + padding (40) < 100
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 0'
)).
padding
,
EdgeInsets
.
zero
);
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 1'
)).
padding
,
EdgeInsets
.
zero
);
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 2'
)).
padding
,
const
EdgeInsets
.
all
(
20
));
expect
(
tester
.
widget
<
Container
>(
find
.
widgetWithText
(
Container
,
'Item 3'
)).
padding
,
const
EdgeInsets
.
all
(
20
));
});
testWidgets
(
'Update PopupMenuItem layout while the menu is visible'
,
(
WidgetTester
tester
)
async
{
final
Key
popupMenuButtonKey
=
UniqueKey
();
final
Type
menuItemType
=
const
PopupMenuItem
<
String
>(
child:
Text
(
'item'
)).
runtimeType
;
...
...
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