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