OverlayEntry.remove() 不会从 overlayState 中删除条目

OverlayEntry.remove() doesn't remove the entry from the overlayState

我正在使用 Flutter 1.2.1 编写一个 flutter 应用程序。

在我的 StatefulWidgetinitState() 中,我调用了我使用以下代码创建的 showOverlay() 函数:

 void showOverlay(BuildContext context) async {
    final OverlayState overlayState = Overlay.of(context);
    final OverlayEntry overlayEntry = OverlayEntry(
      builder: (BuildContext context)=>Positioned(
        left: 0.0,
        right: 0,
        bottom: 90.0,
        child: Container(
            margin: const EdgeInsets.all(15.0),
            padding: const EdgeInsets.all(3.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(25.0),
                border: Border.all(color: Colors.blueAccent)
            ),
          child:
                Text('Focus, lighting and contrast help',style: TextStyle(fontWeight: FontWeight.normal,
                    color: Colors.white,
                    fontSize: 18.0,
                    decoration: TextDecoration.none)),

          )
        ),
    );
    overlayState.insert(overlayEntry);
    await Future<dynamic>.delayed(Duration(seconds: 2));
    overlayEntry.remove();

  }

问题是在延迟 2 秒后,叠加层仍然绘制在屏幕上。

我错过了什么?

谢谢

调试时,我注意到以下警告:

This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.

我用谷歌搜索并发现了这个问题: https://github.com/flutter/flutter/issues/21638

为了解决这个问题,我更改了

overlayState.insert(overlayEntry);

对此:

WidgetsBinding.instance.addPostFrameCallback((_) => overlayState.insert(overlayEntry));

对于尝试上述建议的方法后仍然需要解决方案的任何人。我花了几个小时才找到问题。如果您的代码碰巧多次插入覆盖条目对象,则无法删除它。比如不小心执行了几次插入overlay的代码:

overlayEntry = _overlayEntryBuilder();
Overlay.of(context).insert(overlayEntry));

然后尝试删除:

  overlayEntry?.remove();
  overlayEntry = null;

仅当您调用

时删除才有效
Overlay.of(context).insert(overlayEntry)); 

一次。如果您多次调用它并且删除将不起作用,它可能会创建多个实例,它将在您的应用程序上保持活动状态。如果你不恰当地使用 onChanged 或 .listen 触发器,你可能很容易遇到这种情况。