🔥🔥🔥Flutter中Overlay全局显示浮层,支持自由切换

1,144 阅读1分钟

背景

【问】:如何实现一个新手引导页的管理类?

【问】:如何实现一个可以更换内容的全局悬浮窗?

我的答案是Overlay

overlay_manager实现

import 'package:flutter/widgets.dart';

class OverlayManager {
  OverlayManager._privateConstructor(bool status);

  static final OverlayManager _instance =
      OverlayManager._privateConstructor(false);
  OverlayEntry? _entry;
  BuildContext? _context;

  //初始化单例,在根入口完成最好
  static initInstance(BuildContext context) {
    _instance._context = context;
    return _instance;
  }
  //获取单例
  static OverlayManager getInstance() {
    assert(_instance._context != null);
    return _instance;
  }

  showOverlay(bool show, {Widget widget = const Text('暂无内容')}) {
    assert(_context != null);
    if (show) {
      _entry = _handleEntry(widget);
      Overlay.of(_context!)?.insert(_entry!);
    } else {
      if (_entry!.mounted) {
        _entry!.remove();
      }
    }
  }

  OverlayEntry _handleEntry(Widget widget) {
    if (_entry != null) {
      if (_entry!.mounted) {
        _entry!.remove();
      }
    }
    OverlayEntry entry = OverlayEntry(builder: (context) => widget);
    return entry;
  }
}

单例的初始化

创建一个单例的Overlay管理类,Overlay是需要与BuildContext关联的,渲染第一帧之后初始化单例的同时把BuildContext传递过去。_getOverlayWidget()生成一个自定义的widget

@override
void initState() {
  super.initState();
  WidgetsBinding.instance?.addPostFrameCallback((callback) {
    OverlayManager.initInstance(context).showOverlay(true, widget: _getOverlayWidget());
  });
}

浮层的显示

_getNewOverlayWidget()可以替换为新的要显示的widget,可以自由切换

OverlayManager.getInstance().showOverlay(true, widget: _getNewOverlayWidget());

浮层的隐藏

OverlayManager.getInstance().showOverlay(false);