Flutter桌面端(Windows/Mac/Linux)多窗口实现方案咨询
Flutter桌面多窗口实现方案(托盘+欢迎+设置三窗口场景)
Flutter官方确实未原生支持多窗口,针对你的场景,推荐使用desktop_multi_window(负责多窗口创建)和window_manager(负责窗口生命周期、托盘管理)这两个包,以下是简洁实现示例:
1. 依赖配置
在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter desktop_multi_window: ^0.3.0 window_manager: ^0.3.4
2. 全局初始化
在main.dart的入口函数中完成基础初始化:
import 'package:flutter/material.dart'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:window_manager/window_manager.dart'; import 'dart:convert'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化窗口管理器 await windowManager.ensureInitialized(); // 配置多窗口标题映射 DesktopMultiWindow.setWindowTitleGetter((windowId) { switch(windowId) { case 1: return "欢迎窗口"; case 2: return "设置窗口"; default: return "主托盘窗口"; } }); // 启动时优先打开欢迎窗口 await DesktopMultiWindow.createWindow(jsonEncode({ 'route': '/welcome', })); runApp(const MyApp()); }
3. 各窗口实现
主托盘窗口(内容展示)
主窗口关联系统托盘,实现点击显示/隐藏逻辑:
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> with WindowListener { @override void initState() { super.initState(); windowManager.addListener(this); _initSystemTray(); } // 初始化系统托盘 void _initSystemTray() async { await windowManager.setPreventClose(true); // 关闭时最小化到托盘 final tray = TrayManager.instance; await tray.setIcon('assets/tray_icon.png'); // 替换为你的托盘图标路径 await tray.setContextMenu([ MenuItem(label: '显示窗口', onClick: () => windowManager.show()), MenuItem(label: '退出', onClick: () => exit(0)), ]); } // 拦截窗口关闭事件,转为隐藏 @override void onWindowClose() async { await windowManager.hide(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("主托盘窗口")), body: Center( child: ElevatedButton( onPressed: () async { // 打开设置窗口 await DesktopMultiWindow.createWindow(jsonEncode({ 'route': '/settings', })); }, child: const Text("打开设置"), ), ), ); } }
欢迎窗口(启动弹窗)
添加路由处理器,创建独立的欢迎页面:
// 多窗口路由处理逻辑 Widget handleWindowRoute(Map<String, dynamic> args) { switch(args['route']) { case '/welcome': return const WelcomePage(); case '/settings': return const SettingsPage(); default: return const MyApp(); } } // 欢迎窗口页面 class WelcomePage extends StatelessWidget { const WelcomePage({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("欢迎使用")), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text("欢迎来到我的应用!"), const SizedBox(height: 20), ElevatedButton( onPressed: () => DesktopMultiWindow.closeWindow(1), // 关闭当前欢迎窗口 child: const Text("开始使用"), ), ], ), ), ), ); } }
设置窗口
创建独立的设置页面:
class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("应用设置")), body: const Center( child: Text("这里是设置内容区域"), ), ), ); } }
关键注意事项
- 每个窗口拥有独立的Flutter Engine,需注意内存占用控制
- 窗口间通信可通过
DesktopMultiWindow.sendData和DesktopMultiWindow.setDataHandler实现 - 不同平台(Windows/macOS/Linux)的窗口样式、托盘图标配置可能略有差异,需针对性调整
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

