Changing RawMenuAnchor close order
Closing a `RawMenuAnchor` now triggers `onClose` and `onCloseRequested` callbacks for all descendant `RawMenuAnchor`s in a coordinated sequence.
Summary
#
Closing a RawMenuAnchor now triggers the onCloseRequested
and onClose callbacks for all descendant RawMenuAnchors.
The onCloseRequested callback is triggered top-down,
starting from the triggering RawMenuAnchor and moving to its descendants,
while the onClose callback is triggered bottom-up.
If a RawMenuAnchor is already closed,
calls to MenuController.close and MenuController.closeChildren
don't trigger the onCloseRequested callback.
Background
#
RawMenuAnchor is a low-level widget used to build custom menu systems.
Previously, a RawMenuAnchor didn't automatically
notify its descendants when it was closed.
You had to manually call controller.closeChildren()
within the onCloseRequested callback
to close descendant RawMenuAnchors.
Furthermore, the onClose callback timing was inconsistent.
A parent RawMenuAnchor's onClose could be executed
before its descendants had finished closing.
The updated behavior ensures that when a parent RawMenuAnchor begins to close,
it subsequently triggers onCloseRequested for all of its
descendant RawMenuAnchors in a top-down manner.
When hideOverlay is called from within onCloseRequested to close the menu,
all descendant RawMenuAnchors have their onClose callbacks
executed in a bottom-up order.
This means that the most recently opened RawMenuAnchor
now has its onClose callback executed first,
followed by its parent, and so on up the hierarchy.
This design allows for a coordinated closing sequence
where child RawMenuAnchors can perform any necessary cleanup
before their parents finalize the closing process.
Finally, if a RawMenuAnchor is already closed,
calls to MenuController.close and MenuController.closeChildren
don't trigger the onCloseRequested callback,
preventing unnecessary callback executions.
Migration guide
#
If your code does not override the default implementation of
RawMenuAnchor.onCloseRequested or your RawMenuAnchor
does not contain submenus, no changes are required.
If you have a custom implementation of onCloseRequested
in a RawMenuAnchor containing submenus,
controller.closeChildren() is now called automatically
when the parent menu closes.
Make sure that your implementation of onCloseRequested
still behaves correctly with this automatic call.
Immediate calls to controller.closeChildren() within your
onCloseRequested callback are no longer necessary.
Remove those calls.
Additionally, if your logic relied on the
parent's onClose callback firing before its descendants,
refactor your code to account for the new bottom-up execution order.
Code before migration:
RawMenuAnchor(
controller: menuController,
onCloseRequested: (hideOverlay) {
if (!animationController.isForwardOrCompleted) {
return;
}
// Descendant submenus must be closed before the parent menu.
// This is now handled automatically, so this call is no longer necessary.
menuController.closeChildren();
animationController.reverse().whenComplete(hideOverlay);
},
onClose: () {
// This might have executed before descendants called onClose().
_handleMenuClosed();
},
// ...
)
Code after migration:
RawMenuAnchor(
controller: menuController,
onCloseRequested: (hideOverlay) {
if (!animationController.isForwardOrCompleted) {
return;
}
// `menuController.closeChildren()` is now called automatically.
animationController.reverse().whenComplete(hideOverlay);
},
onClose: () {
// This now executes only after all descendant submenus have
// called `onClose()`.
_handleMenuClosed();
},
// ...
)
Timeline
#
Landed in version: 3.44.0-0.1.pre
In stable release: 3.44
References
#API documentation:
Relevant issues:
Relevant PRs:
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-05-20. View source or report an issue.