在Flutter中添加OverlayEntry

时间:2018-07-24 08:16:24

标签: flutter

我正在尝试将容器插入到叠加层中,但是此代码出现错误。

class _MyHomePageState extends State<MyHomePage> {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final entry = OverlayEntry(builder: (BuildContext overlayContext) {
      return Container(
        height: 50.0,
        width: 50.0,
        color: Colors.blue,
      );
    });
    _addOverlay(entry);
  }

  void _addOverlay(OverlayEntry entry) async {
    Overlay.of(context).insert(entry);
  }

  @override
  Widget build(BuildContext context) {
   return Scaffold(
      appBar: AppBar(
        title: Text('Flutter'),
      ),
      body: Center(),
    );
  }
}

这是错误

  在构建过程中调用

setState()或markNeedsBuild()。不能将此Overlay小部件标记为需要构建,因为框架已在构建小部件的过程中。仅当其某个祖先当前正在构建窗口小部件时,才可以将其标记为需要在构建阶段中构建。允许使用此异常是因为该框架在子代之前构建父窗口小部件,这意味着将始终构建脏后代。否则,在此构建阶段,框架可能不会访问此小部件...

谢谢。

2 个答案:

答案 0 :(得分:2)

自从上次更新为0.8.1以来,我也注意到了这一变化。我修复了此问题,以在最小延迟后添加叠加层

Timer.run(() { Overlay.of(context).insert(calendarOverlay);});

现在这有效,但是感觉就像是被黑客入侵了……

因此,在我的构建中,当叠加层应自行显示时,我将使用此代码。

如果有人有更好的解决方案,我很感兴趣;-)

约翰

更新:我发现此代码也可以使用:

final overlay = Overlay.of(context);
WidgetsBinding.instance.addPostFrameCallback((_) => overlay.insert(entry));

它使我免于加入计时器...

答案 1 :(得分:0)

只分享我的一些发现。我也将在我的应用程序中实现覆盖。因此通过搜索找到了这个SO问题。

许多人在普通窗口小部件之前构建叠加层。例如,在您的代码中,在构建didChangeDependencies之前将调用Scaffold中的覆盖插入。这是所有异步问题的原因。我发现人们这样做(将覆盖插入和相应的普通窗口小部件耦合到有状态的窗口小部件中)是因为他们想找到相应的子窗口小部件的位置,但是子窗口小部件是在覆盖插入调用之后构建的,因此必须将覆盖插入在异步功能中。

但是,如果仅在构建普通窗口小部件后调用覆盖插入(使覆盖插入调用独立于构建基本窗口小部件。将它们分离/分离),则根本不需要任何异步或Timer函数。在我当前的实现中,我将它们分开只是为了使代码安全(我认为它更安全)。因此,不需要任何异步调用。