快速开始
按照以下步骤快速开始使用 window_manager
插件:
安装
将以下内容添加到您的软件包的 pubspec.yaml
文件中:
yaml
dependencies:
window_manager: ^0.4.2
或者
yaml
dependencies:
window_manager:
git:
url: https://github.com/leanflutter/window_manager.git
ref: main
使用方法
dart
import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 必须添加这一行
await windowManager.ensureInitialized();
WindowOptions windowOptions = WindowOptions(
size: Size(800, 600),
center: true,
backgroundColor: Colors.transparent,
skipTaskbar: false,
titleBarStyle: TitleBarStyle.hidden,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.show();
await windowManager.focus();
});
runApp(MyApp());
}
完整示例请参见此插件的示例应用。
监听事件
dart
import 'package:flutter/cupertino.dart';
import 'package:window_manager/window_manager.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with WindowListener {
@override
void initState() {
super.initState();
windowManager.addListener(this);
}
@override
void dispose() {
windowManager.removeListener(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
// ...
}
@override
void onWindowEvent(String eventName) {
print('[WindowManager] onWindowEvent: $eventName');
}
@override
void onWindowClose() {
// 做些什么
}
@override
void onWindowFocus() {
// 做些什么
}
@override
void onWindowBlur() {
// 做些什么
}
@override
void onWindowMaximize() {
// 做些什么
}
@override
void onWindowUnmaximize() {
// 做些什么
}
@override
void onWindowMinimize() {
// 做些什么
}
@override
void onWindowRestore() {
// 做些什么
}
@override
void onWindowResize() {
// 做些什么
}
@override
void onWindowMove() {
// 做些什么
}
@override
void onWindowEnterFullScreen() {
// 做些什么
}
@override
void onWindowLeaveFullScreen() {
// 做些什么
}
}
关闭时退出
如果您需要使用隐藏方法,您需要禁用 QuitOnClose
。
macOS
按如下方式更改文件 macos/Runner/AppDelegate.swift
:
diff
import Cocoa
import FlutterMacOS
@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
- return true
+ return false
}
}
关闭前确认
dart
import 'package:flutter/cupertino.dart';
import 'package:window_manager/window_manager.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with WindowListener {
@override
void initState() {
super.initState();
windowManager.addListener(this);
_init();
}
@override
void dispose() {
windowManager.removeListener(this);
super.dispose();
}
void _init() async {
// 添加此行以覆盖默认的关闭处理程序
await windowManager.setPreventClose(true);
setState(() {});
}
@override
Widget build(BuildContext context) {
// ...
}
@override
void onWindowClose() async {
bool _isPreventClose = await windowManager.isPreventClose();
if (_isPreventClose) {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('您确定要关闭此窗口吗?'),
actions: [
TextButton(
child: Text('否'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('是'),
onPressed: () {
Navigator.of(context).pop();
await windowManager.destroy();
},
),
],
);
},
);
}
}
}
启动时隐藏
在启动 Flutter 桌面应用程序时,可能会有一个短暂的时刻,其中显示未样式化的窗口,然后才应用自定义样式。这可能会为用户创造一种不连贯的视觉体验。
为了防止这种情况,我们可以最初隐藏窗口,只有在 Flutter 完全初始化并应用所有样式后才显示它。这创造了更平滑的启动体验。
以下是如何实现这一点:
Linux
按如下方式更改文件 linux/my_application.cc
:
diff
...
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
...
gtk_window_set_default_size(window, 1280, 720);
- gtk_widget_show(GTK_WIDGET(window));
+ gtk_widget_realize(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
...
macOS
按如下方式更改文件 macos/Runner/MainFlutterWindow.swift
:
diff
import Cocoa
import FlutterMacOS
+import window_manager
class MainFlutterWindow: NSWindow {
override func awakeFromNib() {
let flutterViewController = FlutterViewController.init()
let windowFrame = self.frame
self.contentViewController = flutterViewController
self.setFrame(windowFrame, display: true)
RegisterGeneratedPlugins(registry: flutterViewController)
super.awakeFromNib()
}
+ override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
+ super.order(place, relativeTo: otherWin)
+ hiddenWindowAtLaunch()
+ }
}
Windows
按如下方式更改文件 windows/runner/win32_window.cpp
:
diff
bool Win32Window::CreateAndShow(const std::wstring& title,
const Point& origin,
const Size& size) {
...
HWND window = CreateWindow(
- window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ window_class, title.c_str(),
+ WS_OVERLAPPEDWINDOW, // 不要添加 WS_VISIBLE,因为窗口将在稍后显示
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this);
自 flutter 3.7 新的 windows 项目以来 按如下方式更改文件 windows/runner/flutter_window.cpp
:
diff
bool FlutterWindow::OnCreate() {
...
flutter_controller_->engine()->SetNextFrameCallback([&]() {
- this->Show();
+ "" //删除 this->Show()
});
确保在 onWindowFocus
事件上调用一次 setState
。
dart
import 'package:flutter/cupertino.dart';
import 'package:window_manager/window_manager.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with WindowListener {
@override
void initState() {
super.initState();
windowManager.addListener(this);
}
@override
void dispose() {
windowManager.removeListener(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
// ...
}
@override
void onWindowFocus() {
// 确保只调用一次
setState(() {});
// 做些什么
}
}