如何在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; } }
关键注意点
- 全局NavigatorKey:必须给MaterialApp设置全局
navigatorKey,确保能在任意位置获取全局OverlayState,保证Overlay插入到正确层级 - OverlayEntry引用持有:全局持有
_overlayEntry引用,避免被GC回收导致UI意外消失 - 页面跳转兼容性:只要页面在同一个Navigator栈中,Overlay会持续显示;多Navigator场景需单独处理
- 点击穿透设置:若需要红色边框区域不拦截底层页面点击,给红色Container添加
color: Colors.transparent, pointerEvents: PointerEvents.none - 样式自定义:可根据需求调整边框宽度、对话框位置/样式、按钮数量及功能逻辑
内容的提问来源于stack exchange,提问作者amit.flutter
相关产品推荐
相关产品推荐

