如何检测小部件外的点击?

Fre*_* L. 6 flutter

我有一个按下按钮时显示的菜单,我希望能够在菜单外有 Tap 时关闭菜单,就像常规PopupMenuButton.

我目前的解决方案是使用Stack具有一个GestureDetector作为一个其子检测水龙头,但这种解决方案我的定位是由控制的Stack,我只是想对齐通过菜单的家长控制不是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))
        )
      ]
    ); 
Run Code Online (Sandbox Code Playgroud)

Ale*_*sey 29

在 Flutter 中有一个简单的方法可以做到这一点:

TapRegion(
  onTapInside: (tap) {
    print('On Tap Inside!!');
  },
  onTapOutside: (tap) {
    print('On Tap Outside!!');
  },
  child: ...,
)
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是当前的解决方案?问题是“在小部件之外”而不是对话框!我们应该区分路由的东西和原始的小部件! (3认同)

Mar*_*lle 5

您可以使用自定义路由实现此行为:

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);
}
Run Code Online (Sandbox Code Playgroud)

barrierDismissible倍率表示如果路由应堆的当微件之外检测的触摸被弹出。每当您想显示菜单时,您都可以调用Navigator.of(context).push(CustomDialog()).

此解决方案不允许菜单返回任何值,如果您需要从中返回数据,则可以改写 ModalRoute 并获得类似的结果。