Flutter开发

Flutter开发windows应用手记(一)

2024-01-12  本文已影响0人  非新生代菜鸟

序言

一直做移动app开发,最近项目需要,着手第一个windows应用开发,从0到1,算是边学边用吧。
首先做技术分析,开发windows应用最常用的方案,便是microsoft官方的visualStudio,github上许多项目都是采用vs加C#开发的,由于自己的技术储备是Flutter,而flutter官方是支持桌面应用开发的,所以更加倾向于选择flutter.
网上查了个遍,关于flutter开发桌面应用的博文太少了。看到几篇都是旧版本的,根本用不了,于是选择走官方文档路线。

新手上路

  1. 依据官方文档,安装开发环境。

Windows 的额外要求
要开发 Windows 桌面程序,除了 Flutter SDK,你还需要做以下准备:

  • Visual Studio 2022Visual Studio 2022 生成工具 在选择安装 Visual Studio 时或只安装生成工具的时候,你需要选择「使用 C++ 的桌面开发」,包括其所有默认组件,以安装必要的 C++ 工具链和 Windows SDK 的头文件。
  1. 创建一个包含桌面支持的新应用
flutter create my_app
# 根目录下
cd my_app
flutter run -d windows
# flutter run -d macos
  1. 为已有的应用添加桌面支持
#从项目根目录在控制台运行下面命令:
 flutter create --platforms=windows,macos,linux .

设置创建窗口属性

  1. 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());
  1. 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
  1. 创建基类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,
      };
}
  1. 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),即可看到效果。

上一篇 下一篇

猜你喜欢

热点阅读