概念
系統(tǒng)托盤:系統(tǒng)托盤是一種用戶界面元素,通常出現(xiàn)在操作系統(tǒng)的任務(wù)欄或桌面頂部。它是一個(gè)水平的狹長(zhǎng)區(qū)域,用于顯示各種圖標(biāo)和通知,以提供快速訪問和操作特定應(yīng)用程序或系統(tǒng)功能。系統(tǒng)托盤通常包含操作系統(tǒng)或第三方應(yīng)用程序的圖標(biāo),這些圖標(biāo)可以顯示有關(guān)應(yīng)用程序狀態(tài)、提醒和通知等信息。用戶可以通過單擊這些圖標(biāo)來打開應(yīng)用程序的主窗口、執(zhí)行特定功能或查看詳細(xì)信息。系統(tǒng)托盤的設(shè)計(jì)旨在提供一種方便的方式來管理和訪問常用的應(yīng)用程序和系統(tǒng)功能,以提高用戶的工作效率。
效果展示
作為現(xiàn)代操作系統(tǒng)中常見的一個(gè)組件,系統(tǒng)托盤能夠讓用戶方便地訪問常用的應(yīng)用程序或者系統(tǒng)功能。對(duì)于Flutter桌面應(yīng)用程序開發(fā)者來說,如何在應(yīng)用程序中定義系統(tǒng)托盤是一個(gè)值得探討的問題。本文將簡(jiǎn)介系統(tǒng)托盤的概念,并介紹兩種可用的Flutter桌面應(yīng)用程序系統(tǒng)托盤方案。
實(shí)現(xiàn)方案
1. tray_manager
依賴庫
tray_manager
支持平臺(tái)
Windows, macOS & Linux文章來源:http://www.zghlxwxcb.cn/news/detail-759696.html
實(shí)現(xiàn)步驟
- 在pubspec.yaml中添加依賴
dependencies:
...
tray_manager: ^0.2.0
- 導(dǎo)入依賴
import 'package:flutter/material.dart' hide MenuItem;
import 'package:tray_manager/tray_manager.dart';
- 配置系統(tǒng)托盤特性
Future<void> _init() async {
//設(shè)置系統(tǒng)托盤圖標(biāo),Windows圖標(biāo)必須文件后綴必須是.ico
await trayManager.setIcon(
Platform.isWindows
? 'assets/images/tray_icon_original.ico'
: 'assets/images/img_1.png',
);
//設(shè)置系統(tǒng)托盤的標(biāo)題
trayManager.setTitle("system tray");
//設(shè)置系統(tǒng)托盤的標(biāo)題
trayManager.setToolTip("How to use system tray with Flutter:鼠標(biāo)滑過提示");
//設(shè)置系統(tǒng)托盤的菜單
Menu menu = Menu(
items: [
//設(shè)置系統(tǒng)托盤的子菜單
MenuItem.submenu(
// key
key: 'window_settings',
label: '窗口設(shè)置',
//trayManager 不支持菜單項(xiàng)添加圖標(biāo),該配置無效
icon: Platform.isWindows
? 'assets/images/app_icon.bmp'
: 'assets/images/img_1.png',
submenu: Menu(items: [
MenuItem.checkbox(
checked: true,
label: "毛玻璃效果",
onClick: (MenuItem menuItem) {
menuItem.checked = !(menuItem.checked == true);
if (kDebugMode) {
print("毛玻璃效果 onClick ${menuItem.checked}");
}
},
),
MenuItem.checkbox(
checked: true,
label: "窗口置頂",
onClick: (MenuItem menuItem) {
menuItem.checked = !(menuItem.checked == true);
if (kDebugMode) {
print("窗口置頂 onClick ${menuItem.checked}");
}
},
),
MenuItem.checkbox(
checked: true,
label: "自啟動(dòng)",
onClick: (MenuItem menuItem) {
menuItem.checked = !(menuItem.checked == true);
if (kDebugMode) {
print("自啟動(dòng) onClick ${menuItem.checked}");
}
},
),
//可選類型的菜單欄
MenuItem.checkbox(
checked: true,
label: "圖標(biāo)閃爍",
onClick: (MenuItem menuItem) {
menuItem.checked = !(menuItem.checked == true);
if (kDebugMode) {
print("圖標(biāo)閃爍 onClick ${menuItem.checked}");
}
},
),
])),
//分割線
MenuItem.separator(),
MenuItem(
key: 'open_app',
label: 'Open App',
onClick: (MenuItem menuItem) {
}),
MenuItem(
key: 'exit_app',
label: 'Exit App',
onClick: (MenuItem menuItem) {
}),
],
);
if (kDebugMode) {
print("menu:${menu.toJson()}");
}
//為系統(tǒng)托盤配置菜單
await trayManager.setContextMenu(menu);
}
- 監(jiān)聽TrayListener
import 'package:flutter/material.dart';
import 'package:tray_manager/tray_manager.dart';
class HomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TrayListener {
void initState() {
trayManager.addListener(this);
super.initState();
_init();
}
void dispose() {
trayManager.removeListener(this);
super.dispose();
}
void _init() {
// ...
}
Widget build(BuildContext context) {
// ...
}
//未觸發(fā)該事件
void onTrayIconRightMouseUp() {
// TODO: implement onTrayIconRightMouseUp
super.onTrayIconRightMouseUp();
if (kDebugMode) {
print("onTrayIconMouseUp");
}
}
//未觸發(fā)該事件
void onTrayIconMouseUp() {
super.onTrayIconMouseUp();
if (kDebugMode) {
print("onTrayIconMouseUp");
}
}
void onTrayIconMouseDown() {
if (kDebugMode) {
print("onTrayIconMouseDown");
}
//彈出托盤的菜單欄
trayManager.popUpContextMenu();
}
void onTrayIconRightMouseDown() {
if (kDebugMode) {
print("onTrayIconRightMouseDown");
}
//彈出托盤的菜單欄
trayManager.popUpContextMenu();
}
//彈出托盤的菜單欄點(diǎn)擊事件
void onTrayMenuItemClick(MenuItem menuItem) {
if (kDebugMode) {
print("menuItem:${menuItem.key}-${menuItem.label}");
}
}
}
2. system_tray
依賴庫
system_tray
支持平臺(tái)
Windows, macOS & Linux
實(shí)現(xiàn)步驟
- 在pubspec.yaml中添加依賴
dependencies:
...
system_tray: ^2.0.3
- 導(dǎo)入依賴
import 'package:system_tray/system_tray.dart';
- 配置系統(tǒng)托盤特性
//創(chuàng)建SystemTray 對(duì)象
final SystemTray _systemTray = SystemTray();
Timer? _timer;
//配置系統(tǒng)托盤
Future<void> _initSystemTray() async {
//設(shè)置系統(tǒng)托盤的圖標(biāo),必須是.ico后綴的圖片
await _systemTray.initSystemTray(
iconPath: Platform.isWindows
? 'assets/images/tray_icon_original.ico'
: 'assets/images/img_1.png',
);
//設(shè)置系統(tǒng)托盤的標(biāo)題
_systemTray.setTitle("system tray");
//設(shè)置系統(tǒng)托盤的提示
_systemTray.setToolTip("How to use system tray with Flutter");
//注冊(cè)系統(tǒng)托盤事件
_systemTray.registerSystemTrayEventHandler((eventName) {
debugPrint("eventName: $eventName");
//注冊(cè)系統(tǒng)托盤事件:點(diǎn)擊事件
if (eventName == kSystemTrayEventClick) {
//Windows系統(tǒng):顯示主窗口 其他系統(tǒng)彈出托盤菜單彈框
Platform.isWindows
? windowManager.show()
: _systemTray.popUpContextMenu();
//注冊(cè)系統(tǒng)托盤事件:鼠鍵右鍵
} else if (eventName == kSystemTrayEventRightClick) {
//Windows系統(tǒng):彈出托盤菜單彈框 其他系統(tǒng): 顯示主窗口
Platform.isWindows
? _systemTray.popUpContextMenu()
: windowManager.show();
}
});
//創(chuàng)建托盤的菜單
final Menu _menuMain = Menu();
await _menuMain.buildFrom([
//創(chuàng)建子菜單
SubMenu(
label: "窗口設(shè)置",
//創(chuàng)建為菜單子項(xiàng)添加圖標(biāo),格式必須是bmp
image: Platform.isWindows
? 'assets/images/app_icon.bmp'
: 'assets/images/img_1.png',
children: [
//創(chuàng)建可選框類型的菜單項(xiàng)
MenuItemCheckbox(
label: "毛玻璃效果",
checked: true,
name: 'acrylic_cb',
onClicked: (MenuItemBase menuItem) async {
//更新MenuItemCheckbox的狀態(tài)
await menuItem.setCheck(!menuItem.checked);
if (kDebugMode) {
print("毛玻璃效果 onClick ${menuItem.checked}");
}
if (menuItem.checked == true) {
showAcrylic(color);
} else {
closeAcrylic();
}
}),
MenuItemCheckbox(
label: "窗口置頂",
checked: true,
onClicked: (MenuItemBase menuItem) async {
await menuItem.setCheck(!menuItem.checked);
if (kDebugMode) {
print("窗口置頂 onClick ${menuItem.checked}");
}
if (menuItem.checked == true) {
windowManager.setAlwaysOnTop(true);
} else {
windowManager.setAlwaysOnTop(false);
}
}),
MenuItemCheckbox(
label: "自啟動(dòng)",
checked: true,
name: 'auto_start_cb',
onClicked: (MenuItemBase menuItem) async {
// menuItem.checked = !(menuItem.checked == true);
await menuItem.setCheck(!menuItem.checked);
if (kDebugMode) {
print("自啟動(dòng) onClick ${menuItem.checked}");
}
}),
MenuItemCheckbox(
label: "圖標(biāo)閃爍",
checked: true,
name: "flash_cb",
onClicked: (MenuItemBase menuItem) async {
MenuItemCheckbox? flashCb =
_menuMain.findItemByName<MenuItemCheckbox>("flash_cb");
await flashCb?.setCheck(!menuItem.checked);
if (kDebugMode) {
print("圖標(biāo)閃爍 onClick ${menuItem.checked}");
}
if (menuItem.checked) {
startFlashIcon();
} else {
stopFlashIcon();
}
}),
]),
//菜單分割線
MenuSeparator(),
//菜單項(xiàng)
MenuItemLabel(
label: 'Open App',
image: Platform.isWindows
? 'assets/images/app_icon.bmp'
: 'assets/images/img_1.png',
onClicked: (MenuItemBase menuItem) {
windowManager.show();
}),
MenuItemLabel(
label: 'Exit App',
image: Platform.isWindows
? 'assets/images/app_icon.bmp'
: 'assets/images/img_1.png',
onClicked: (MenuItemBase menuItem) {
windowManager.close();
}),
]);
if (kDebugMode) {
print("menu:${_menuMain.toString()}");
}
//為系統(tǒng)托盤設(shè)置菜單項(xiàng)
await _systemTray.setContextMenu(_menuMain);
}
- 完整代碼
import 'package:flutter/material.dart';
import 'package:tray_manager/tray_manager.dart';
class HomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Timer? _timer;
final SystemTray _systemTray = SystemTray();
void initState() {
super.initState();
_initSystemTray();
}
void dispose() {
_timer.cancel();
super.dispose();
}
void _initSystemTray() {
// ...
}
//開始圖標(biāo)閃爍
void startFlashIcon() {
if (kDebugMode) {
print("startFlashIcon");
}
var imageList = const [
"assets/images/tray_icon_original.ico",
"assets/images/tray_icon.ico"
];
var index = 0;
_timer =
Timer.periodic(const Duration(milliseconds: 500), (Timer timer) async {
if (kDebugMode) {
print("path:${imageList[index]}");
}
await _systemTray.setImage(imageList[index]);
index = (index == 0) ? 1 : 0;
});
}
//停止圖標(biāo)閃爍
void stopFlashIcon() async {
if (kDebugMode) {
print("stopFlashIcon");
}
_timer?.cancel();
_timer = null;
await _systemTray.setImage("assets/images/tray_icon_original.ico");
}
Widget build(BuildContext context) {
// ...
}
}
3. 兩種方案對(duì)比
system_tray 支持菜單項(xiàng)添加圖標(biāo),tray_manager不支持菜單項(xiàng)添加圖標(biāo)
4. 注意事項(xiàng)
Windows平臺(tái)系統(tǒng)托盤圖標(biāo)需要是以.ico后綴的圖片,菜單項(xiàng)圖標(biāo)需要是.bmp后綴的圖片,否則圖片無法顯示;文章來源地址http://www.zghlxwxcb.cn/news/detail-759696.html
5. 話題拓展
- BMP格式(Bitmap):BMP是一種無損的位圖圖像格式,最初由Microsoft開發(fā)。它可以存儲(chǔ)圖像的像素顏色和位置信息,并支持不同的色彩深度。BMP文件通常較大,因?yàn)樗鼈儾唤?jīng)過壓縮,保留了圖像的每個(gè)像素的完整信息。BMP格式適用于Windows系統(tǒng)和一些圖像編輯軟件。
- ICO格式(Icon):ICO是一種用于存儲(chǔ)圖標(biāo)的文件格式。ICO文件通常用于表示計(jì)算機(jī)系統(tǒng)上的各種圖標(biāo),例如文件夾、應(yīng)用程序和網(wǎng)站等的圖標(biāo)。ICO文件可以包含多個(gè)圖標(biāo)大小和顏色深度的版本,以適應(yīng)不同的顯示需求。ICO文件可以在Windows系統(tǒng)中直接使用,也可以在網(wǎng)頁或應(yīng)用程序中使用。
到了這里,關(guān)于Flutter桌面應(yīng)用程序定義系統(tǒng)托盤Tray的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!