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

Flutter桌面应用开发:实现启动仅显示托盘、默认隐藏主窗口

Flutter跨桌面应用启动时默认隐藏主窗口并仅显示托盘的实现方法

要实现启动时仅显示托盘、默认隐藏主窗口,且可通过托盘打开窗口的效果,我们可以结合system_tray(系统托盘管理)和window_manager(窗口状态控制)两个包来完成,以下是具体步骤:

1. 添加依赖

在pubspec.yaml中引入所需依赖:

dependencies:
  flutter:
    sdk: flutter
  system_tray: ^2.0.0
  window_manager: ^0.3.0

执行flutter pub get安装依赖。

2. 核心实现代码

在main.dart中完成窗口初始化、托盘配置:

import 'package:flutter/material.dart';
import 'package:system_tray/system_tray.dart';
import 'package:window_manager/window_manager.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化窗口管理器
  await windowManager.ensureInitialized();
  
  // 配置窗口默认隐藏
  WindowOptions windowOptions = const WindowOptions(
    visible: false, // 关键:启动时不显示窗口
    size: Size(800, 600), // 设置默认窗口尺寸
  );
  windowManager.waitUntilReadyToShow(windowOptions, () async {
    await windowManager.hide(); // 确保窗口处于隐藏状态
  });

  runApp(const MyApp());
  
  // 初始化系统托盘
  await initSystemTray();
}

// 初始化系统托盘及菜单
Future<void> initSystemTray() async {
  final SystemTray systemTray = SystemTray();
  
  // 设置托盘图标(替换为你自己的图标路径,注意平台格式差异:macOS用.icns,Windows用.ico,Linux用.png)
  String iconPath = 'assets/icons/tray_icon.png';
  await systemTray.initSystemTray(
    iconPath: iconPath,
    toolTip: '我的Flutter桌面应用', // 鼠标悬停托盘时的提示文本
  );

  // 构建托盘右键菜单
  final Menu menu = Menu();
  await menu.buildFrom([
    MenuItemLabel(
      label: '打开主窗口',
      onClicked: () async {
        await windowManager.show(); // 显示主窗口
        await windowManager.focus(); // 让窗口获得焦点
      },
    ),
    MenuItemSeparator(), // 菜单分隔线
    MenuItemLabel(
      label: '退出应用',
      onClicked: () {
        systemTray.destroy(); // 销毁托盘
        windowManager.close(); // 关闭窗口并退出应用
      },
    ),
  ]);
  
  // 绑定菜单到托盘
  await systemTray.setContextMenu(menu);
  
  // 可选:点击托盘图标时直接打开窗口
  systemTray.registerSystemTrayEventHandler((eventName) {
    if (eventName == kSystemTrayEventClick) {
      windowManager.show();
      windowManager.focus();
    }
  });
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Tray App',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('主窗口')),
      body: const Center(child: Text('这是主窗口内容')),
    );
  }
}

3. 平台特定注意事项

  • 图标配置:确保在pubspec.yaml中声明了图标资源路径,例如:
    flutter:
      assets:
        - assets/icons/
    
  • macOS:在macos/Runner/Info.plist中添加权限说明(可选):
    <key>NSStatusBarUsageDescription</key>
    <string>需要访问状态栏以显示应用托盘</string>
    
  • Linux:部分发行版需安装依赖库,执行命令:
    sudo apt-get install libayatana-appindicator3-dev
    
  • Windows:托盘图标建议使用.ico格式,避免显示异常。

内容的提问来源于stack exchange,提问作者Matan Shushan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:10:32