序言
一直做移动app开发,最近项目需要,着手第一个windows应用开发,从0到1,算是边学边用吧。
首先做技术分析,开发windows应用最常用的方案,便是microsoft官方的visualStudio,github上许多项目都是采用vs加C#开发的,由于自己的技术储备是Flutter,而flutter官方是支持桌面应用开发的,所以更加倾向于选择flutter.
网上查了个遍,关于flutter开发桌面应用的博文太少了。看到几篇都是旧版本的,根本用不了,于是选择走官方文档路线。
新手上路
- 依据官方文档,安装开发环境。
Windows 的额外要求
要开发 Windows 桌面程序,除了 Flutter SDK,你还需要做以下准备:
- Visual Studio 2022 或 Visual Studio 2022 生成工具 在选择安装 Visual Studio 时或只安装生成工具的时候,你需要选择「使用 C++ 的桌面开发」,包括其所有默认组件,以安装必要的 C++ 工具链和 Windows SDK 的头文件。
- 创建一个包含桌面支持的新应用
flutter create my_app
# 根目录下
cd my_app
flutter run -d windows
# flutter run -d macos
- 为已有的应用添加桌面支持
#从项目根目录在控制台运行下面命令:
flutter create --platforms=windows,macos,linux .
设置创建窗口属性
- windows/runner/main.cpp文件中:
int screenWidth = GetSystemMetrics(SM_CXSCREEN); // 获取屏幕宽度
int screenHeight = GetSystemMetrics(SM_CYSCREEN); // 获取屏幕高度
FlutterWindow window(project);
Win32Window::Point origin(screenWidth/2 - 600, screenHeight/2 - 350);
Win32Window::Size size(1200, 700);
if (!window.CreateAndShow(chineseString, origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);
// 将窗口置于前台
SetForegroundWindow(window.GetHandle());
- pubspec.yaml文件中引入window_manager(窗口管理库)和system_tray(管理右下角状态栏图标):
dependencies:
flutter:
sdk: flutter
get: ^4.6.5
rxdart: ^0.27.3
path_provider: ^2.0.11
connectivity_plus: ^5.0.1
logger: ^1.1.0
intl: ^0.18.0
flutter_localization: ^0.1.12
flutter_phoenix: ^1.1.1
dio: ^5.1.1
dio_cache_interceptor: ^3.4.2
shared_preferences: ^2.0.8
encrypt: ^5.0.1
pull_to_refresh: ^2.0.0
lottie: ^1.4.1
fast_cached_network_image: ^1.2.0
flutter_widget_from_html_core: ^0.10.3
qr_flutter: ^4.1.0
dart_ping: ^9.0.0
auto_size_text: ^3.0.0
url_launcher: ^6.1.12
image_picker: ^1.0.1
crop_image: ^1.0.10
image_compression: ^1.0.4
package_info_plus: ^4.1.0
clipboard: ^0.1.3
file_picker: ^6.1.1
window_manager: ^0.3.4
system_tray: ^2.0.3
- 创建基类baseApp:
class BaseApp extends StatefulWidget {
const BaseApp({Key? key}) : super(key: key);
@override
State<BaseApp> createState() => _BaseAppState();
}
class _BaseAppState extends State<BaseApp> with WidgetsBindingObserver {
@override
Widget build(BuildContext context) {
// 见window_manager官方文档
final virtualWindowFrameBuilder = VirtualWindowFrameInit();
return RefreshConfiguration(
hideFooterWhenNotFull: false, // Viewport不满一屏时,禁用上拉加载更多功能
enableBallisticLoad: true, // 可以通过惯性滑动触发加载更多
child: GetMaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
debugShowCheckedModeBanner: false,
initialRoute: AppPages.initial,
getPages: AppPages.routes,
builder: (context, child) {
child = virtualWindowFrameBuilder(context, child);
return child;
},
//home: const SizedBox(),
),
);
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
- lib/main.dart文件中:
import 'package:fast_cached_network_image/fast_cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
import 'base/base_app.dart';
import 'common/global.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Global.init();
// 初始化网络图片缓存时间
await FastCachedImageConfig.init(clearCacheAfter: const Duration(days: 1));
await windowManager.ensureInitialized();
WindowOptions windowOptions = const WindowOptions(
size: Size(1200, 700),
backgroundColor: Colors.transparent,
skipTaskbar: false,
titleBarStyle: TitleBarStyle.hidden,
title: "软件名称",
windowButtonVisibility: false,
// alwaysOnTop: true,
center: true,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
windowManager.setAsFrameless(); //无边框
windowManager.setHasShadow(false); //这里不能有阴影,否则会出现一个透明外框
windowManager.setMaximizable(false);
windowManager.setResizable(false);
// windowManager.setAlwaysOnTop(true); //始终置于其它应用上层
await windowManager.show();
await windowManager.focus();
});
runApp(const BaseApp());
}
至此,一个基本框架已经搭建好了,运行目标选择Windows(desktop),即可看到效果。
网友评论