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
4dd70652
Unverified
Commit
4dd70652
authored
Aug 14, 2022
by
Ademir Villena
Committed by
GitHub
Aug 14, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add onOpened callback to PopupMenuButton (#103753)
parent
5fcd9c25
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
84 additions
and
1 deletion
+84
-1
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+5
-0
popup_menu_test.dart
packages/flutter/test/material/popup_menu_test.dart
+79
-1
No files found.
packages/flutter/lib/src/material/popup_menu.dart
View file @
4dd70652
...
...
@@ -1009,6 +1009,7 @@ class PopupMenuButton<T> extends StatefulWidget {
super
.
key
,
required
this
.
itemBuilder
,
this
.
initialValue
,
this
.
onOpened
,
this
.
onSelected
,
this
.
onCanceled
,
this
.
tooltip
,
...
...
@@ -1039,6 +1040,9 @@ class PopupMenuButton<T> extends StatefulWidget {
/// The value of the menu item, if any, that should be highlighted when the menu opens.
final
T
?
initialValue
;
/// Called when the popup menu is shown.
final
VoidCallback
?
onOpened
;
/// Called when the user selects a value from the popup menu created by this button.
///
/// If the popup menu is dismissed without selecting a value, [onCanceled] is
...
...
@@ -1204,6 +1208,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
final
List
<
PopupMenuEntry
<
T
>>
items
=
widget
.
itemBuilder
(
context
);
// Only show the menu if there is something to show
if
(
items
.
isNotEmpty
)
{
widget
.
onOpened
?.
call
();
showMenu
<
T
?>(
context:
context
,
elevation:
widget
.
elevation
??
popupMenuTheme
.
elevation
,
...
...
packages/flutter/test/material/popup_menu_test.dart
View file @
4dd70652
...
...
@@ -64,6 +64,75 @@ void main() {
expect
(
find
.
text
(
'Next'
),
findsOneWidget
);
});
testWidgets
(
'PopupMenuButton calls onOpened callback when the menu is opened'
,
(
WidgetTester
tester
)
async
{
int
opens
=
0
;
late
BuildContext
popupContext
;
final
Key
noItemsKey
=
UniqueKey
();
final
Key
noCallbackKey
=
UniqueKey
();
final
Key
withCallbackKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
Column
(
children:
<
Widget
>[
PopupMenuButton
<
int
>(
key:
noItemsKey
,
itemBuilder:
(
BuildContext
context
)
{
return
<
PopupMenuEntry
<
int
>>[];
},
onOpened:
()
=>
opens
++,
),
PopupMenuButton
<
int
>(
key:
noCallbackKey
,
itemBuilder:
(
BuildContext
context
)
{
popupContext
=
context
;
return
<
PopupMenuEntry
<
int
>>[
const
PopupMenuItem
<
int
>(
value:
1
,
child:
Text
(
'Tap me please!'
),
),
];
},
),
PopupMenuButton
<
int
>(
key:
withCallbackKey
,
itemBuilder:
(
BuildContext
context
)
{
return
<
PopupMenuEntry
<
int
>>[
const
PopupMenuItem
<
int
>(
value:
1
,
child:
Text
(
'Tap me, too!'
),
),
];
},
onOpened:
()
=>
opens
++,
),
],
),
),
),
);
// Make sure callback is not called when the menu is not shown
await
tester
.
tap
(
find
.
byKey
(
noItemsKey
));
await
tester
.
pump
();
expect
(
opens
,
equals
(
0
));
// Make sure everything works if no callback is provided
await
tester
.
tap
(
find
.
byKey
(
noCallbackKey
));
await
tester
.
pump
();
expect
(
opens
,
equals
(
0
));
// Close the opened menu
Navigator
.
of
(
popupContext
).
pop
();
await
tester
.
pump
();
// Make sure callback is called when the button is tapped
await
tester
.
tap
(
find
.
byKey
(
withCallbackKey
));
await
tester
.
pump
();
expect
(
opens
,
equals
(
1
));
});
testWidgets
(
'PopupMenuButton calls onCanceled callback when an item is not selected'
,
(
WidgetTester
tester
)
async
{
int
cancels
=
0
;
late
BuildContext
popupContext
;
...
...
@@ -130,9 +199,10 @@ void main() {
expect
(
cancels
,
equals
(
2
));
});
testWidgets
(
'disabled PopupMenuButton will not call itemBuilder, onSelected or onCanceled'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'disabled PopupMenuButton will not call itemBuilder, on
Opened, on
Selected or onCanceled'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
popupButtonKey
=
GlobalKey
();
bool
itemBuilderCalled
=
false
;
bool
onOpenedCalled
=
false
;
bool
onSelectedCalled
=
false
;
bool
onCanceledCalled
=
false
;
...
...
@@ -158,6 +228,7 @@ void main() {
),
];
},
onOpened:
()=>
onOpenedCalled
=
true
,
onSelected:
(
int
selected
)
=>
onSelectedCalled
=
true
,
onCanceled:
()
=>
onCanceledCalled
=
true
,
),
...
...
@@ -177,6 +248,7 @@ void main() {
await
tester
.
tap
(
find
.
byKey
(
popupButtonKey
));
await
tester
.
pumpAndSettle
();
expect
(
itemBuilderCalled
,
isFalse
);
expect
(
onOpenedCalled
,
isFalse
);
expect
(
onSelectedCalled
,
isFalse
);
// Try to bring up the popup menu and tap outside it to cancel the menu
...
...
@@ -185,6 +257,7 @@ void main() {
await
tester
.
tapAt
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
itemBuilderCalled
,
isFalse
);
expect
(
onOpenedCalled
,
isFalse
);
expect
(
onCanceledCalled
,
isFalse
);
// Test again, with directional navigation mode and after focusing the button.
...
...
@@ -198,6 +271,7 @@ void main() {
await
tester
.
tap
(
find
.
byKey
(
popupButtonKey
));
await
tester
.
pumpAndSettle
();
expect
(
itemBuilderCalled
,
isFalse
);
expect
(
onOpenedCalled
,
isFalse
);
expect
(
onSelectedCalled
,
isFalse
);
// Try to bring up the popup menu and tap outside it to cancel the menu
...
...
@@ -206,6 +280,7 @@ void main() {
await
tester
.
tapAt
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
itemBuilderCalled
,
isFalse
);
expect
(
onOpenedCalled
,
isFalse
);
expect
(
onCanceledCalled
,
isFalse
);
});
...
...
@@ -213,6 +288,7 @@ void main() {
final
Key
popupButtonKey
=
UniqueKey
();
final
GlobalKey
childKey
=
GlobalKey
();
bool
itemBuilderCalled
=
false
;
bool
onOpenedCalled
=
false
;
bool
onSelectedCalled
=
false
;
await
tester
.
pumpWidget
(
...
...
@@ -233,6 +309,7 @@ void main() {
),
];
},
onOpened:
()
=>
onOpenedCalled
=
true
,
onSelected:
(
int
selected
)
=>
onSelectedCalled
=
true
,
),
],
...
...
@@ -245,6 +322,7 @@ void main() {
expect
(
Focus
.
of
(
childKey
.
currentContext
!).
hasPrimaryFocus
,
isFalse
);
expect
(
itemBuilderCalled
,
isFalse
);
expect
(
onOpenedCalled
,
isFalse
);
expect
(
onSelectedCalled
,
isFalse
);
});
...
...
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