Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How detect a tap outside a widget?

Tags:

flutter

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))
        )
      ]
    ); 
like image 399
Freddx L. Avatar asked Apr 02 '19 01:04

Freddx L.


1 Answers

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.

like image 72
Mariano Uvalle Avatar answered Sep 24 '22 10:09

Mariano Uvalle