选信阳水泥隔墙板,要考虑哪些适配条件和选型方法?
2026/8/6 5:43:49
在这篇博客中,笔者会讲诉为什么要实现自定义标题栏,标题栏都有些什么功能,然后结合AI简单实现自定义标题栏!
话不多说,我们直接开始吧!
这篇文档默认你的设备已经配置了flutter环境且自身具备了如下:
Dart语法基础Qt以及其他)flutter空项目->flutter create --empty your_project_nameflutter的心补充说明:
安装flutter环境来这里
dart语法基础来这里
新手入门项目来这里
注意:学习程度因人而异,如果满足的点越多,理论上学习效率越高!
笔者的环境:
64位fedora 43 gnome,桌面系统Wayland,内核版本Linux 6.17.9-300.fc43.x86_64Flutter 3.38.5Dart 3.10.42.51.1Qwen3-Coder模型)我们可以参考常见的应用vscode、QQ、微信等这些在(Windows、Linux和macOS)都有较强的统一风格,这就是自定义标题栏的目的——统一风格
插一嘴:其实自定义标题栏可以避免大量因标题栏样式不统一而导致的问题(比如:
gnome49的标题栏不支持暗色主题等)
我们需要把这个看似复杂的问题简单化,实现自定义标题栏那我们就要知道标题栏的构成:窗口图标、窗口标题、窗口按钮(最小化、最大与还原、关闭)!见下图:
注意:
gnome和macOS不支持窗口图标!
事实窗口标题栏和flutter中的appBar是吻合的,见下图
既然我们已经知道AppBar的功能可以平替窗口标题栏,
那么我们直接隐藏默认的使用AppBar自定义一个不就好了?
关闭系统默认的标题栏
标题栏与AppBar以及功能映射关系
leading-> 显示窗口图标title-> 显示窗口标题actions-> 显示对应图标以及窗口的隐藏,放大复原,关闭window_manager# 终端执行如下:flutter pubaddwindow_manager// 程序顶部添加如下import'package:window_manager/window_manager.dart';voidmain(){runApp(constMyApp());}替换为
voidmain()async{WidgetsFlutterBinding.ensureInitialized();awaitwindowManager.ensureInitialized();WindowOptions windowOptions=WindowOptions(titleBarStyle:TitleBarStyle.hidden,);windowManager.waitUntilReadyToShow(windowOptions,()async{awaitwindowManager.focus();});runApp(constMainApp());}注意: 确保你创建的是空项目
window_manager插件官网
body:Center(child:Text('Hello World!'))//替换为appBar:AppBar(leading:Icon(Icons.favorite),title:Text("自定义标题栏"),actions:[IconButton(onPressed:(){},icon:Icon(Icons.horizontal_rule)),IconButton(onPressed:(){},icon:Icon(Icons.crop_square)),IconButton(onPressed:(){},icon:Icon(Icons.close)),],),显示效果
// 替换为如下:appBar:AppBar(leading:Icon(Icons.favorite),title:Text("自定义标题栏"),actions:[IconButton(onPressed:(){windowManager.minimize();},icon:Icon(Icons.horizontal_rule),),IconButton(onPressed:(){},icon:Icon(Icons.crop_square)),IconButton(onPressed:(){windowManager.close();},icon:Icon(Icons.close),),],),// 将 StatelessWidget 转为StatefulWidget// vscode 选中StatelessWidget 显示代码操作(ctrl.)StatefulWidget// _MainAppState 初始化变量用于记录是否最大化bool _isMaximized=false替换appBar为如下:
appBar:AppBar(leading:Icon(Icons.favorite),title:Text("自定义标题栏"),actions:[IconButton(onPressed:(){windowManager.minimize();},icon:Icon(Icons.horizontal_rule),),IconButton(onPressed:(){if(_isMaximized){windowManager.unmaximize();setState((){_isMaximized=!_isMaximized;});}else{windowManager.maximize();setState((){_isMaximized=!_isMaximized;});}},icon:_isMaximized?Icon(Icons.crop_free):Icon(Icons.crop_square),),IconButton(onPressed:(){windowManager.close();},icon:Icon(Icons.close),),],),显示效果
简单的办法直接监听鼠标事件
//AppBar里添加如下flexibleSpace:Listener(onPointerDown:(_)=>windowManager.startDragging(),child:Container(color:Colors.transparent),),光标带拖动效果我的系统并不支持
flexibleSpace:MouseRegion(cursor:SystemMouseCursors.move,child:Listener(onPointerDown:(_)=>windowManager.startDragging(),child:Container(color:Colors.transparent),),),显示效果
注意:
- 都是长按鼠标左键拖动窗口,右键鼠标 跟随光标移动
- 一定要在Container 中添加颜色为透明 不然无法移动
import'package:flutter/material.dart';import'package:window_manager/window_manager.dart';voidmain()async{WidgetsFlutterBinding.ensureInitialized();awaitwindowManager.ensureInitialized();WindowOptions windowOptions=WindowOptions(titleBarStyle:TitleBarStyle.hidden,);windowManager.waitUntilReadyToShow(windowOptions,()async{awaitwindowManager.focus();});runApp(constMainApp());}classMainAppextendsStatefulWidget{constMainApp({super.key});@overrideState<MainApp>createState()=>_MainAppState();}class_MainAppStateextendsState<MainApp>{bool _isMaximized=false;void_toggleMaximize(){if(_isMaximized){windowManager.unmaximize();}else{windowManager.maximize();}setState(()=>_isMaximized=!_isMaximized);}@overrideWidgetbuild(BuildContext context){returnMaterialApp(home:Scaffold(appBar:AppBar(leading:Icon(Icons.favorite),title:Text('自定义标题栏'),flexibleSpace:Listener(onPointerDown:(event)=>windowManager.startDragging(),child:Container(color:Colors.transparent),),actions:[IconButton(icon:Icon(Icons.horizontal_rule),onPressed:windowManager.minimize,),IconButton(icon:Icon(_isMaximized?Icons.crop_free:Icons.crop_square),onPressed:_toggleMaximize,),IconButton(icon:Icon(Icons.close),onPressed:windowManager.close),],),body:Center(child:Text('Hello, World!')),),);}}通义AI对话过程