Flutter如何自定义macOS的titlebar
在Flutter开发macOS应用时,如何自定义窗口的titlebar样式?目前默认的titlebar与设计风格不匹配,想实现以下功能:
- 隐藏系统默认的titlebar
- 添加自定义按钮(如最小化/关闭)
- 支持拖拽区域调整窗口位置
- 修改标题文字样式和颜色
是否有官方推荐方案或第三方插件可以实现?需要兼容最新的Flutter稳定版。
2 回复
在Flutter中自定义macOS标题栏,可使用window_manager插件。通过setTitleBarStyle方法设置透明或隐藏标题栏,然后使用自定义Widget模拟标题栏。需注意适配macOS系统版本。
更多关于Flutter如何自定义macOS的titlebar的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在 Flutter 中自定义 macOS 应用的 titlebar,可以通过以下步骤实现:
1. 启用 macOS 平台的自定义标题栏
在 macos/Runner/AppDelegate.swift 文件中,修改 applicationDidFinishLaunching 方法,启用无边框窗口并自定义标题栏。
import Cocoa
import FlutterMacOS
class AppDelegate: FlutterAppDelegate {
override func applicationDidFinishLaunching(_ notification: Notification) {
// 获取主窗口
if let window = NSApplication.shared.windows.first {
// 设置为无标题栏风格,以便自定义
window.styleMask.insert(.fullSizeContentView)
window.titlebarAppearsTransparent = true
window.titleVisibility = .hidden
// 可选:隐藏标准窗口按钮(关闭、最小化、最大化)
// window.standardWindowButton(.closeButton)?.isHidden = true
// window.standardWindowButton(.miniaturizeButton)?.isHidden = true
// window.standardWindowButton(.zoomButton)?.isHidden = true
}
super.applicationDidFinishLaunching(notification)
}
}
2. 在 Flutter 中构建自定义标题栏
在 Dart 代码中,使用 AppBar 或自定义 Widget 模拟标题栏,并处理拖拽功能。
import 'package:flutter/material.dart';
class CustomTitleBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 50, // 设置标题栏高度
color: Colors.blue, // 自定义背景色
child: Row(
children: [
// 自定义标题
Padding(
padding: EdgeInsets.only(left: 16),
child: Text(
'自定义标题',
style: TextStyle(color: Colors.white),
),
),
Spacer(),
// 自定义按钮(如关闭、最小化)
WindowButtons(),
],
),
);
}
}
// 自定义窗口按钮(需通过 platform channel 调用原生方法)
class WindowButtons extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(
icon: Icon(Icons.minimize, color: Colors.white),
onPressed: () {
// 调用原生方法最小化窗口
},
),
IconButton(
icon: Icon(Icons.close, color: Colors.white),
onPressed: () {
// 调用原生方法关闭窗口
},
),
],
);
}
}
3. 使用 platform channel 实现窗口控制
若需自定义按钮功能(如关闭、最小化),需通过 platform channel 调用 macOS 原生 API。
- 在 Dart 中定义 channel:
import 'package:flutter/services.dart';
class WindowControl {
static const platform = MethodChannel('window_control');
static Future<void> minimizeWindow() async {
try {
await platform.invokeMethod('minimizeWindow');
} on PlatformException catch (e) {
print("Failed: '${e.message}'.");
}
}
static Future<void> closeWindow() async {
try {
await platform.invokeMethod('closeWindow');
} on PlatformException catch (e) {
print("Failed: '${e.message}'.");
}
}
}
- 在 macOS 中实现 channel 方法(在
AppDelegate.swift中):
override func applicationDidFinishLaunching(_ notification: Notification) {
// 其他设置...
let controller = mainFlutterWindow?.contentViewController as? FlutterViewController
let channel = FlutterMethodChannel(name: "window_control", binaryMessenger: controller!.engine.binaryMessenger)
channel.setMethodCallHandler { call, result in
switch call.method {
case "minimizeWindow":
NSApplication.shared.windows.first?.miniaturize(nil)
result(nil)
case "closeWindow":
NSApplication.shared.windows.first?.close()
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
super.applicationDidFinishLaunching(notification)
}
4. 在 Flutter 界面中使用
将自定义标题栏置于 Scaffold 的 appBar 或直接放在页面顶部。
Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: CustomTitleBar(),
),
body: YourContent(),
);
注意事项:
- 确保
macos/Runner.xcworkspace配置正确,允许无边框窗口。 - 自定义标题栏需处理拖拽移动窗口(默认透明标题栏支持拖拽)。
- 测试窗口按钮功能在不同 macOS 版本下的兼容性。
通过以上步骤,即可在 Flutter 中实现自定义 macOS 标题栏。

