Flutter 开发鸿蒙 PC 第一个应用:窗口创建 + 大屏布局
上一篇我们完成了 Flutter For OpenHarmony 鸿蒙 PC 开发的环境搭建,本篇将聚焦「第一个实战应用」—— 从窗口创建、PC 专属配置到大屏响应式布局,全程拆解开发流程,提供可直接下载复用的工程模板,帮助快速上手鸿蒙 PC 应用开发。
上一篇我们完成了 Flutter For OpenHarmony 鸿蒙 PC 开发的环境搭建,本篇将聚焦「第一个实战应用」—— 从窗口创建、PC 专属配置到大屏响应式布局,全程拆解开发流程,提供可直接下载复用的工程模板,帮助快速上手鸿蒙 PC 应用开发。
一、应用核心目标与技术要点
本次开发的鸿蒙 PC 应用为「基础演示工具」,核心实现以下功能,覆盖 PC 端开发核心场景:
- 鸿蒙 PC 专属窗口创建与配置(固定初始尺寸、支持缩放、窗口标题定制);
- 大屏响应式布局(适配 1080P/2K/4K 分辨率,区分横竖屏显示逻辑);
- PC 键鼠交互基础支持(鼠标悬停效果、滚轮滚动适配);
- 工程模板标准化(便于后续功能扩展与复用)。
核心技术栈:Flutter 3.13.0+ + 鸿蒙 PC SDK(API 11),无额外第三方依赖,确保环境兼容性。
二、工程初始化与目录结构(模板基础)
我们基于上一篇的环境,通过命令行创建标准化工程,同时梳理 PC 端专属目录结构,为窗口配置和布局开发铺垫。
2.1 工程创建
# 进入工作目录(无中文、无空格)
cd D:\FlutterOHOSProjects
# 创建鸿蒙 PC 专属 Flutter 工程(指定设备类型为 PC)
flutter create --template=ohos --device-type=pc flutter_ohos_pc_first_app
# 进入工程目录
cd flutter_ohos_pc_first_app
# 用 DevEco Studio 打开工程(自动关联鸿蒙 SDK)
devecostudio .
2.2 鸿蒙 PC 工程专属目录结构
flutter_ohos_pc_first_app/
├─ entry/ # 鸿蒙应用入口模块(PC 端核心配置目录)
│ └─ src/main/
│ ├─ ets/ # 鸿蒙原生代码目录(窗口配置关联)
│ ├─ resources/ # 资源目录(图标、字符串等)
│ └─ config.json # 核心配置文件(窗口参数、权限等,PC 专属)
├─ lib/ # Flutter 业务代码目录
│ └─ main.dart # 入口文件(布局实现、交互逻辑)
├─ pubspec.yaml # Flutter 依赖配置文件
└─ ohos.yaml # 鸿蒙工程配置文件(关联 Flutter 与鸿蒙原生)
⚠️ 关键提醒:PC 端开发需重点关注
entry/src/main/config.json(窗口配置)和lib/main.dart(布局实现),二者联动实现应用可视化效果,区别于移动端的目录适配逻辑。
三、鸿蒙 PC 窗口创建与专属配置
鸿蒙 PC 应用的窗口特性(尺寸、缩放、标题栏)需通过 config.json 配置,再结合 Flutter 层初始化逻辑,实现窗口的完整创建。
3.1 config.json 窗口核心配置(PC 专属)
路径:entry/src/main/config.json,修改 abilities 节点下的窗口参数,配置后需同步保存工程,具体代码如下:
{
"app": {
"bundleName": "com.example.flutterohospcfirstapp",
"vendor": "example",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"module": {
"name": "entry",
"type": "entry",
"srcPath": "./src/main/ets",
"deviceType": ["pc"], // 仅保留 PC 设备类型,排除其他端
"minAPIVersion": 11,
"abilities": [
{
"name": ".MainAbility",
"type": "page",
"launchType": "standard",
"orientation": "unspecified", # 支持横竖屏自适应(PC 大屏必备)
"windowMode": "windowed", # 窗口模式(fullscreen 为全屏模式)
"defaultWidth": 1280, # 初始宽度(适配 2K 屏基础尺寸)
"defaultHeight": 720, # 初始高度(16:9 黄金比例,适配多数 PC)
"resizable": true, # 允许窗口缩放(PC 端核心交互需求)
"titleBar": true, # 显示系统标题栏(可自定义标题)
"title": "Flutter 鸿蒙 PC 演示应用", # 窗口标题(PC 专属)
"icon": "$media:icon", # 窗口图标(从 resources 目录读取)
"label": "$string:app_name"
}
],
"reqPermissions": [] # 本次无额外权限需求,留空即可
}
}
配置说明:
windowMode:可选windowed(窗口)、fullscreen(全屏),PC 端开发优先选windowed,支持用户手动切换全屏;resizable:必须设为true,否则窗口无法缩放,不符合 PC 端使用习惯;defaultWidth/defaultHeight:建议以 1280x720 为基础,适配主流 PC 分辨率,后续布局通过响应式适配更高分辨率。
3.2 Flutter 层窗口初始化关联
路径:lib/main.dart,初始化 Flutter 应用时,需开启 PC 端键鼠交互支持,确保窗口加载后能响应鼠标悬停、滚轮等事件,基础初始化代码如下:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
// 可选:设置窗口最小尺寸(PC 端专属限制,避免窗口过小导致布局错乱)
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
DeviceOrientation.portraitUp,
]);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 鸿蒙 PC 应用',
theme: ThemeData(
primarySwatch: Colors.blue,
// PC 端字体适配:默认字体略大于移动端,提升大屏可读性
textTheme: const TextTheme(
bodyLarge: TextStyle(fontSize: 16),
bodyMedium: TextStyle(fontSize: 14),
),
),
home: const HomePage(),
// 开启 PC 端鼠标交互支持(悬停、滚轮)
scrollBehavior: const MaterialScrollBehavior().copyWith(
dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
},
),
debugShowCheckedModeBanner: false, // 隐藏调试横幅
);
}
}
四、鸿蒙 PC 大屏响应式布局实现
鸿蒙 PC 端屏幕尺寸差异大(13 寸笔记本到 27 寸显示器),需采用响应式布局,确保在不同分辨率下布局合理、交互流畅。本次实现「左右分栏 + 自适应折叠」布局,核心用 LayoutBuilder 和 MediaQuery 组件。
4.1 完整布局代码(可直接运行)
在 lib/main.dart 中补充 HomePage 组件,实现大屏分栏、小屏折叠的响应式逻辑,同时添加鼠标悬停效果:
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
// 获取当前窗口尺寸,用于响应式判断
final screenSize = MediaQuery.of(context).size;
// 定义分栏阈值:宽度 > 800 时分栏,否则垂直折叠
final isWideScreen = screenSize.width > 800;
return Scaffold(
// PC 端标题栏:结合鸿蒙原生窗口标题,添加自定义操作按钮
appBar: AppBar(
title: const Text('鸿蒙 PC 演示应用'),
toolbarHeight: 48, // PC 端标题栏高度适配(高于移动端的 56)
actions: [
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
// 后续可扩展设置功能
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('设置功能待扩展')),
);
},
tooltip: '设置', // PC 端鼠标悬停提示
hoverColor: Colors.blue[100], // 鼠标悬停背景色
),
],
),
body: LayoutBuilder(
builder: (context, constraints) {
return isWideScreen
? _buildWideScreenLayout(constraints)
: _buildNarrowScreenLayout(constraints);
},
),
);
}
// 宽屏布局(左右分栏)
Widget _buildWideScreenLayout(BoxConstraints constraints) {
return Row(
children: [
// 左侧导航栏(占比 25%,固定宽度不拉伸)
Container(
width: constraints.maxWidth * 0.25,
color: Colors.grey[100],
padding: const EdgeInsets.symmetric(vertical: 20),
child: ListView(
children: [
_buildNavItem('首页', Icons.home),
_buildNavItem('数据展示', Icons.data_usage),
_buildNavItem('关于', Icons.info),
],
),
),
// 右侧内容区(占比 75%,填充剩余空间)
Expanded(
child: Container(
padding: const EdgeInsets.all(30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'鸿蒙 PC 大屏布局演示',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 20),
// 数据卡片(PC 端大屏适配,多卡片横向排列)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildDataCard('在线人数', '128', Colors.blue),
_buildDataCard('运行时长', '24h', Colors.green),
_buildDataCard('版本号', '1.0.0', Colors.orange),
],
),
const SizedBox(height: 30),
const Text(
'布局说明:当前为宽屏模式(宽度 > 800px),采用左右分栏布局,适配 2K/4K 显示器。拖动窗口边缘缩小宽度,将自动切换为垂直布局。',
style: TextStyle(color: Colors.grey[600], fontSize: 14),
),
],
),
),
),
],
);
}
// 窄屏布局(垂直折叠)
Widget _buildNarrowScreenLayout(BoxConstraints constraints) {
return Column(
children: [
// 顶部导航栏(替代左侧分栏)
Container(
height: 56,
color: Colors.grey[100],
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildNavItemNarrow('首页', Icons.home),
_buildNavItemNarrow('数据展示', Icons.data_usage),
_buildNavItemNarrow('关于', Icons.info),
],
),
),
// 下方内容区
Expanded(
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'鸿蒙 PC 窄屏布局演示',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 20),
// 数据卡片(垂直排列)
Column(
children: [
_buildDataCard('在线人数', '128', Colors.blue),
const SizedBox(height: 15),
_buildDataCard('运行时长', '24h', Colors.green),
const SizedBox(height: 15),
_buildDataCard('版本号', '1.0.0', Colors.orange),
],
),
],
),
),
),
],
);
}
// 宽屏导航项(带鼠标悬停效果)
Widget _buildNavItem(String title, IconData icon) {
return ListTile(
leading: Icon(icon, color: Colors.blue),
title: Text(title),
onTap: () {},
hoverTileColor: Colors.blue[50], // 鼠标悬停背景色
selectedTileColor: Colors.blue[100],
selected: title == '首页', // 默认选中首页
);
}
// 窄屏导航项
Widget _buildNavItemNarrow(String title, IconData icon) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: Colors.blue),
const SizedBox(height: 4),
Text(title, style: const TextStyle(fontSize: 12)),
],
);
}
// 数据卡片组件(复用)
Widget _buildDataCard(String title, String value, Color color) {
return Container(
width: 180,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey[200],
blurRadius: 4,
offset: const Offset(0, 2),
),
],
borderLeft: Border(left: BorderSide(color: color, width: 4)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: TextStyle(color: Colors.grey[600], fontSize: 14)),
const SizedBox(height: 8),
Text(
value,
style: TextStyle(color: color, fontSize: 22, fontWeight: FontWeight.bold),
),
],
),
);
}
}
4.2 布局核心适配要点(PC 端专属)
- 分栏阈值设定:以 800px 为分界,宽屏时分栏、窄屏时折叠,适配笔记本小屏与台式机大屏;
- 组件尺寸适配:PC 端标题栏高度、字体大小、卡片尺寸均大于移动端,提升大屏操作与阅读体验;
- 键鼠交互优化:添加
hoverColor、tooltip等鼠标悬停特性,符合 PC 端操作习惯,区别于移动端的触摸交互; - 布局复用:提取
_buildDataCard、_buildNavItem等复用组件,降低后续扩展成本。
五、应用运行与效果验证
5.1 运行步骤(同前序流程,简化版)
- 启动鸿蒙 PC 模拟器(或连接真机):在 DevEco Studio 工具栏打开「Device Manager」,启动已创建的 PC 模拟器(推荐 1280x720 分辨率);
- 运行应用:点击工具栏「Run 'entry'」(绿色三角按钮),IDE 自动编译工程并安装到模拟器;
- 效果验证:应用启动后,观察窗口特性与布局适配效果。
5.2 核心验证点
| 验证项 | 预期效果 |
|---|---|
| 窗口特性 | 初始尺寸 1280x720,可拖动边缘缩放,标题栏显示「Flutter 鸿蒙 PC 演示应用」 |
| 布局适配 | 窗口宽度 > 800px 时左右分栏,< 800px 时垂直折叠,布局自动重绘 |
| 键鼠交互 | 鼠标悬停导航项时显示背景色,点击设置图标弹出提示,滚轮可滚动内容区 |
六、可运行工程模板获取与使用
6.1 模板获取
- 访问鸿蒙开发者社区,搜索「Flutter 鸿蒙 PC 第一个应用模板」;
- 下载模板压缩包,解压至无中文路径(如:D:\FlutterTemplates);
- 用 DevEco Studio 打开解压后的工程,自动加载依赖(首次打开需等待 npm 安装依赖)。
6.2 模板使用注意事项
- 依赖校验:打开工程后,执行
flutter ohos doctor校验依赖,确保无报错; - 包名修改:根据自身需求修改
config.json中的bundleName(需唯一,遵循反向域名规则); - 图标替换:替换
entry/src/main/resources/media目录下的图标文件,适配 PC 端窗口图标显示。
七、常见问题排查
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| 窗口无法缩放 | config.json 中 resizable 设为 false,或未配置该参数 |
修改 resizable 为 true,保存后重新编译运行 |
| 鼠标悬停无效果 | Flutter 层未配置 scrollBehavior 支持鼠标设备 |
参照 3.2 节代码,添加鼠标设备支持配置 |
| 布局错乱(组件重叠) | 未使用 LayoutBuilder 或 MediaQuery,固定了组件绝对尺寸 |
替换为响应式布局逻辑,用相对尺寸(占比、自适应)替代绝对尺寸 |
| 应用启动后无窗口标题 | 未在 config.json 中配置 title 参数 |
补充 title 字段,设置自定义窗口标题 |
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
更多推荐


所有评论(0)