flutter OverLay添加浮窗的问题及处理

最近在使用OverLay添加浮窗的时候,遇到个问题,在某个界面上弹出浮窗,界面跳转,浮窗仍然存在

研究发现,使用Overlay.of(context)来获取overlay的时候,会获取到最近的overlay,如果不做处理,一般会获取到MaterialApp中的navigator创建的Overlay。此时的overlay是全局的,如果当前界面收到某些事件回调导致跳转,会导致上述现象。

解决方法:可以在需要展示浮窗的界面顶层嵌套一层overlay,然后使用Overlay.of(context)获取到的就是当前界面的overlay,界面跳转即会消失

@override
  Widget build(BuildContext context) {
    TWLog("_DetailPageState build...");
    // return _buildBody(context);
    return Overlay(
      initialEntries: [
        OverlayEntry(
          builder: (context) {
            _logic.detailState.overlayContext = context;
            return _buildBody(context);
          },
        ),
      ],
    );
  }

添加蒙层

  void showVideoTipLayer() {
    // 获取当前页面overlay
    var overlayContext = detailState.overlayContext;
    if (overlayContext == null) {
      return;
    }
    var overlay = Overlay.of(overlayContext);
    if (overlay == null) {
      return;
    }
    detailState.videoTipEntry = OverlayEntry(builder: (_) {
      return DetailVideoTipView(videoViewHeight: DetailHeaderView.getHeight(), closeAction: () {
        // 释放
        detailState.videoTipEntry?.remove();
        detailState.videoTipEntry = null;
      },);
    });
    overlay.insert(detailState.videoTipEntry!); // 添加浮窗
  }

这种写法虽然可以正常实现浮窗的创建和移除,但是会引发另外的问题,每次添加浮窗,都会使当前的树结构重构,所有的widget重新build,可能会出现某些界面布局问题

针对这种情况,对写法进行了改进,总结出下面的方案,具体写法如下:

1.准备工作 添加属性

  /// 当前页Overlay的context
  BuildContext? overlayContext;

  /// 蒙层
  OverlayEntry? videoTipEntry;
  1. 界面使用stack布局嵌套两层视图,顶部添加Overlay,底部添加需要创建的界面
Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: const BoxConstraints.expand(),
      child: Stack(
        children: [
          _buildBody(context), // 实际界面布局
          Overlay(
            initialEntries: [
              OverlayEntry(
                builder: (context) {
                  _logic.detailState.overlayContext = context;
                  return const SizedBox();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
  1. 在适合的地方完成浮窗创建和添加,注意不要忘记释放
/// 添加蒙层
  void showVideoTipLayer() {
    // 获取当前页面overlay
    var overlayContext = detailState.overlayContext;
    if (overlayContext == null) {
      return;
    }
    var overlay = Overlay.of(overlayContext);
    if (overlay == null) {
      return;
    }
    detailState.videoTipEntry = OverlayEntry(builder: (_) {
      return DetailVideoTipView(videoViewHeight: DetailHeaderView.getHeight(), closeAction: () {
        // 释放
        detailState.videoTipEntry?.remove();
        detailState.videoTipEntry = null;
      },);
    });
    overlay.insert(detailState.videoTipEntry!); // 添加浮窗
  }

这样就可以方便的针对某个界面添加独有的浮窗啦

你可能感兴趣的:(flutter OverLay添加浮窗的问题及处理)