如何在flutter的弹出窗口小部件下使整个屏幕处于非活动状态(变暗)(类似于showDialog)?

时间:2019-05-23 17:30:45

标签: flutter

我在Scaffold中有一个“添加”浮动操作按钮。单击“添加”浮动动作按钮时,它将在原始浮动动作按钮上方创建两个更多的浮动动作按钮,以便用户可以选择要单击的浮动动作按钮。

当另外两个浮动操作按钮处于活动/弹出状态时,我希望整个屏幕变得模糊/黑暗而处于非活动状态,类似于调用showDialog()的效果。这样,只有三个浮动操作按钮处于活动状态,而所有其他屏幕部件均处于非活动状态并且呈暗/模糊状态。

最后,通过单击非活动区域,将取消两个浮动操作按钮。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

我找到了两种方法来实现这一目标。

使用PopupRoute

我阅读了Flutter框架代码,发现showDialog实际上正在使用PopupRoute。基本上,这将创建一个新路由并使上一个路由页面处于非活动状态。

最简单的代码如下:

class MyPopupRoute extends PopupRoute<void> {
  @override
  Color get barrierColor => Colors.black54;

  @override
  bool get barrierDismissible => true;
  @override
  String get barrierLabel => "Close";

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => MyPopupPage();

  @override
  Duration get transitionDuration => const Duration(milliseconds: 300);
}

其中MyPopupPage是新的弹出窗口小部件。

如果要动画,可以覆盖方法buildTransitions。只需查看API文档以了解更多详细信息。

带有重叠

非常感谢@ 01leo提供这种方式。 Flutter Challenge: Feature Discovery video包含有关如何使用它的详细说明。基本上,只需使用Overlay.of(context).insert(overlayEntry);,叠加层就好像是当前内置页面顶部的隐藏堆栈。

在我撰写此答案时,视频作者提供的代码无法在最新版本中使用(飞镖2)。您必须将叠加层插入程序包装在Timer.run(() { Overlay.of(context).insert(calendarOverlay);});之类的计时器中,以解决此问题并使代码运行。

根据我的发现,作者之所以需要对覆盖插入的异步函数调用是因为它将覆盖的创建与有状态小部件中的普通小部件结合在一起。而且,当状态更改时,将在构建子级小部件之前调用覆盖插入,并且覆盖层需要知道子级的位置,但尚未创建子级小部件。如果您不希望异步调用覆盖插入,则可以简单地将覆盖的创建与相应的普通窗口小部件分离。这样,您可以简单地正常调用叠加插入。但是,使用这种同步方式,您可能无法轻松找到正常的小部件位置。 (顺便说一句,我在这里使用“普通小部件”一词,但这不是很正确。我还没有找到一个合适的英文词。)

答案 1 :(得分:1)

我无法提供任何代码,但是showDialog()和类似方法使用了集成在Overlay中的Scaffold。可以使用Overlay.of(context)进行访问。它实际上是整个Stack中的Scaffold,您可以在所有内容的顶部插入项目。

要更深入地了解Overlay和代码示例,我建议观看此Flutter Challenge: Feature Discovery