You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter的GetX路由中全局叠加屏幕共享Overlay Widget

Flutter 全局屏幕共享 Overlay UI 实现方案

核心思路

通过OverlayEntry实现全局悬浮UI,它独立于页面路由层级,能在页面跳转时保持显示。核心实现两点:

  • 红色全屏边框:用Container包裹整个屏幕区域,设置红色边框样式
  • 操作对话框:用Positioned定位在屏幕指定位置,包含功能按钮

完整代码实现

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const HomePage(),
      navigatorKey: ScreenShareOverlay.navigatorKey, // 全局导航Key
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('首页')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => ScreenShareOverlay.show(),
          child: const Text('开启屏幕共享'),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const SecondPage())),
        child: const Icon(Icons.navigate_next),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('第二页')),
      body: const Center(child: Text('页面跳转后共享UI依然显示')),
    );
  }
}

class ScreenShareOverlay {
  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  static OverlayEntry? _overlayEntry;

  // 显示共享UI
  static void show() {
    if (_overlayEntry != null) return;

    _overlayEntry = OverlayEntry(builder: (context) {
      return Stack(
        children: [
          // 红色全屏边框
          Positioned.fill(
            child: Container(
              decoration: BoxDecoration(
                border: Border.all(color: Colors.red, width: 4),
              ),
            ),
          ),
          // 底部操作对话框
          Positioned(
            bottom: 20,
            left: 20,
            right: 20,
            child: Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(12),
                boxShadow: const [BoxShadow(color: Colors.black26, blurRadius: 8)],
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
                    onPressed: hide,
                    child: const Text('停止共享'),
                  ),
                  ElevatedButton(
                    onPressed: () {}, // 自定义设置逻辑
                    child: const Text('设置'),
                  ),
                  ElevatedButton(
                    onPressed: () {}, // 自定义画质调整逻辑
                    child: const Text('画质'),
                  ),
                ],
              ),
            ),
          ),
        ],
      );
    });

    navigatorKey.currentState?.overlay?.insert(_overlayEntry!);
  }

  // 隐藏共享UI
  static void hide() {
    _overlayEntry?.remove();
    _overlayEntry = null;
  }
}

关键注意点

  1. 全局NavigatorKey:必须给MaterialApp设置全局navigatorKey,确保能在任意位置获取全局OverlayState,保证Overlay插入到正确层级
  2. OverlayEntry引用持有:全局持有_overlayEntry引用,避免被GC回收导致UI意外消失
  3. 页面跳转兼容性:只要页面在同一个Navigator栈中,Overlay会持续显示;多Navigator场景需单独处理
  4. 点击穿透设置:若需要红色边框区域不拦截底层页面点击,给红色Container添加color: Colors.transparent, pointerEvents: PointerEvents.none
  5. 样式自定义:可根据需求调整边框宽度、对话框位置/样式、按钮数量及功能逻辑

内容的提问来源于stack exchange,提问作者amit.flutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:47:10