不喜欢古板的GUI标题栏?优雅无边框(Frameless)窗口Flutter也可以有

818 阅读4分钟

在现代软件开发中,用户界面的美观性和用户体验至关重要。

无边框窗口因其简洁的设计和高度的可定制性而受到许多开发者的青睐。Flutter,作为一个跨平台的UI工具包,允许开发者快速在iOS和Android上构建高质量的原生界面。而window_manager是一个Flutter插件,它提供了一个简单的方式来创建和管理无边框窗口。

本文将详细介绍如何使用Flutter和window_manager插件来开发无边框窗口。

Flutter是一个由Google开发的开源移动应用SDK,它允许开发者使用Dart语言来构建跨平台的移动应用。Flutter的特点是高性能、可定制性强,并且拥有丰富的组件库。它允许开发者通过编写一次代码,就能在iOS和Android平台上运行,极大地提高了开发效率。

window_manager是一个Flutter插件,它提供了对窗口管理的控制,包括创建无边框窗口、调整窗口大小和位置等。通过这个插件,开发者可以在Flutter应用中实现更加灵活的窗口管理。

01. 初步实现

开始之前,确保你可以创建并运行Flutter项目

a. 添加window_manager依赖

在你的Flutter项目的pubspec.yaml文件中添加window_manager的依赖:

dependencies:  
  flutter:  
    sdk: flutter  
  window_manager: ^0.4.3
  # 其他依赖
  ... 

然后运行flutter pub get来安装依赖。

b. 加载windowManager,初始化Flutter应用

Flutter应用入口代码main函数里添加windowManager初始化代码

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

// 默认main函数声明没有async关键字
// 由于部分代码需要异步调用,因此需要加上async支持内部含有异步调用
void main() async {

	// 这里可以理解为Flutter引擎和Native桥接的初始化
	// 大多数只涉及普通UI渲染的Widget的开发一般不需要这个
	// 但如果使用一些插件用到和原生Android或iOS等系统原生交互的时候
	// 使用插件功能前,需要在使用插件之前先初始化这个
	WidgetsFlutterBinding.ensureInitialized();

	// 初始化windowManager插件功能
	await windowManager.ensureInitialized();  

	// windows_manager接管窗口渲染参数,可以按需要参照文档调整
	WindowOptions windowOptions = const WindowOptions(  
	  size: Size(200, 100),  // 默认窗口尺寸
	  center: false,  
	  backgroundColor: Colors.transparent,  
	  skipTaskbar: false,  
	  titleBarStyle: TitleBarStyle.hidden,  
	  windowButtonVisibility: false,  
	);  

	// 窗口显示之前将上边的显示参数应用到组件
	windowManager.waitUntilReadyToShow(windowOptions, () async {  
	  await windowManager.setAsFrameless();  
	});

  runApp(MyApp());
}


让window_manager托管整个App的组件树

class MyApp extends StatefulWidget {
	... // 默认App组件
}

class _MyAppState extends State<MyApp> {
	// build里加入window_manager托管代码
	@override  
	Widget build(BuildContext context) {  
	  // 创建window_manager的窗口管理器组件,替代Flutter默认Scaffold窗口组件
	  final virtualWindowFrameBuilder = VirtualWindowFrameInit();

		return MaterialApp(  
		    debugShowCheckedModeBanner: false,  
		    builder: (context, child) {  
		      child = virtualWindowFrameBuilder(context, child);  
		      return child;  
		    },  
		    navigatorObservers: [],  
		    // home字段指向的组件即为应用组件入口,可以使用任何Flutter内建组件或插件开发界面
		    // 只不过整个窗口外观是由window_manager定制管理
		    // 加入drag事件检测,可以在无边框情况下也可以拖动
			home: GestureDetector(  
			    behavior: HitTestBehavior.translucent,  
			    onPanStart: (details) {  
			      windowManager.startDragging();  
			    },  
			    child: Container(  
			      color: Colors.deepPurple,  
			    )  
			),
		);
	}
}

c. 运行测试

Pasted image 20241105123949.png

由于没有了系统内置的顶部标题栏,所以关闭和最小最大化也没了,接下来实现这部分窗口管理功能

02. 无边框窗口管理实现

window_manager里包含了窗口管理的相关实现,比如最大最小化关闭拖拽等,因此只需要加上对应的UI元素调用这些实现事件即可。

a. 窗口管理按钮代码

这三个按钮可以用一个Row布局,最小化最大化关闭三个按钮依次排放。

定义一个窗口是否已最大化状态: 如已最大化,最大化窗口按钮则显示为还原为上一次窗口尺寸 如未最大化,则最大化窗口按钮显示为最大化窗口尺寸

bool _isMaximized = false;

窗口管理按钮对应调用windowManager的窗口管理函数,即可实现窗口自定义管理。

Row(  
  children: [  
    IconButton(  
      alignment: Alignment.center,  
      icon: Icon(  
        Icons.horizontal_rule_rounded,  
      ),  
      onPressed: () {  
        windowManager.minimize();  
      },  
    ),  
    IconButton(  
      icon: Icon(  
        _isMaximized ? Icons.fullscreen_exit : Icons.fullscreen,  
      ),  
      onPressed: maximizeWindow,  
    ),  
    IconButton(  
      icon: Icon(  
        Icons.close,  
      ),  
      onPressed: () {  
        windowManager.close();  
      },  
    ),  
  ],  
)

b. 运行测试

Pasted image 20250606130422.png

03. 总结

通过使用Flutter和window_manager插件,开发者可以轻松地在跨平台应用中实现无边框窗口。这不仅提高了应用的美观性,也为用户提供了更加沉浸的体验。

请注意,以上代码和步骤是一个基本的指南,实际开发中可能需要根据具体需求进行调整。