I have a menu that is displayed when a button is pressed, I want to be able to close the menu when there is a Tap outside the menu, just like a regular PopupMenuButton
.
My current solution is use a Stack
that have a GestureDetector
as one of its children to detect the taps but with this solution my alignment is controlled by the Stack
, I just want the alignment to be controlled by the parent of the menu not the Stack
.
//part of the build method
return Stack(
fit: StackFit.expand,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
//Holds the list of menu items
menuContainer,
//button that displays the menu
floatingActionButton]
),
//Detects taps outside the menu
GestureDetector(onTap: (() => setVisibility(false))
)
]
);
You can achieve this behavior using a custom route:
class CustomDialog extends PopupRoute {
@override
Color get barrierColor => Colors.transparent;
@override
bool get barrierDismissible => true;
@override
String get barrierLabel => null;
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return _builder(context);
}
Widget _builder(BuildContext context) {
return Container();
}
@override
Duration get transitionDuration => Duration(milliseconds: 300);
}
The barrierDismissible
override indicates if the route should be popped out of the stack when a touch is detected outside the widget. Whenever you want to show the menu you could call Navigator.of(context).push(CustomDialog())
.
This solution does not allow the menu to return any value, if you need data back from it then you could override ModalRoute instead and achieve a similar result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With