鸿蒙游戏 UI 怎么设计才不乱?
本文针对鸿蒙ArkUI开发中常见的UI混乱问题,提出8个关键优化原则:1)UI只做展示;2)状态单向流动;3)合理拆分组件;4)建立清晰层级;5)避免深层嵌套;6)分离UI状态;7)状态驱动UI;8)多端适配。文章指出,良好的UI架构应实现组件化、分层化和状态管理,避免逻辑与UI混杂,最终形成"Page-Container-Component-Atom"的分层结构。通过规范化设

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
文章目录
引言
很多人刚开始用 ArkUI 写鸿蒙游戏 UI,会有一种错觉:
“声明式 UI,看起来很简单。”
但写着写着就变成这样:
- UI 代码越来越长
- 嵌套越来越深
- 状态到处都是
- 修改一个地方,牵一发动全身
最后你会得到一个典型结果:
UI 不是难写,而是“写乱了”。
在 HarmonyOS 的 ArkUI 体系中:
UI 设计的核心,不是“怎么写”,而是“怎么组织”。
一、先说结论
一个不乱的 UI,一定满足:
1、UI 只做展示(不写逻辑)
2、状态单向流动(Store → UI)
3、组件可复用(拆分)
4、层级清晰(结构化)
如果你现在的 UI:
- 有逻辑
- 有网络
- 有复杂计算
那一定会乱。
二、最常见的“乱 UI”写法
一个页面写完一切
Column() {
Text("玩家")
if (this.score > 10) {
Text("高手")
}
Button("攻击")
.onClick(() => {
this.score++
this.attackEnemy()
})
ForEach(this.list, item => {
Row() {
Image(item.icon)
Text(item.name)
}
})
}
问题:
UI + 逻辑 + 状态 + 渲染 全混在一起
一旦复杂:
完全不可维护
三、第一步:UI 只做“展示”
UI 写逻辑
onClick(() => this.score++)
正确
onClick(() => gameService.addScore())
UI 只负责:
触发事件 + 展示数据
所有逻辑进 Service。
四、第二步:状态只来自 Store
页面维护状态
@State score: number = 0
正确
@State state = gameStore.state
UI 永远只读:
Store → UI
不允许:
UI → 改状态
五、第三步:组件拆分
巨型 UI
Column() {
玩家信息
背包
技能栏
地图
}
拆组件
components
├─ PlayerPanel
├─ InventoryPanel
├─ SkillPanel
└─ MapView
示例
PlayerPanel({ player: this.state.player })
InventoryPanel({ items: this.state.items })
原则:
一个组件,只做一件 UI 事情
六、第四步:组件分层
UI 不只是“拆”,还要“分层”。
推荐分层:
Page(页面)
↓
Container(容器组件)
↓
Component(业务组件)
↓
Atom(基础组件)
示例
Page
GamePage
Container
GameHUD(血量 + 分数 + UI 控制)
Component
PlayerInfo
ScoreBoard
Atom
Icon
Button
Text
好处:
- 层次清晰
- 可复用
- 不会混乱
七、第五步:避免深层嵌套
深层嵌套
Column() {
Row() {
Column() {
Row() {
Text()
}
}
}
}
可读性极差。
拆出去
MainLayout()
PlayerInfo()
原则:
嵌套超过 3 层,就该拆组件
八、第六步:UI 状态分离
有些 UI 状态:
弹窗
loading
选中状态
不应该和业务混在一起。
单独 UI Store
uiStore = {
loading: false,
dialogVisible: false
}
UI 使用
if (this.uiState.loading) {
LoadingView()
}
本质:
UI 状态 ≠ 游戏状态
九、第七步:状态驱动 UI
ArkUI 最大优势:
状态变化 → UI 自动更新
示例
Text(`Score: ${this.state.score}`)
不要写:
this.updateUI()
一切交给状态。
十、第八步:UI 与多端适配
鸿蒙特点:
手机 / 平板 / TV
写死布局
width(300)
响应式
if (device.type === 'tv') {
width(600)
}
或使用自适应布局。
十一、最终 UI 结构
pages
└─ GamePage
components
├─ hud
├─ player
├─ battle
└─ common
页面代码
@Entry
@Component
struct GamePage {
@State state = gameStore.state
build() {
Column() {
GameHUD({ state: this.state })
PlayerPanel({ player: this.state.player })
BattleView({ battle: this.state.battle })
}
}
}
页面非常干净。
十二、判断 UI 是否“健康”
有这些问题:
- 页面超过 500 行
- 嵌套很深
- 到处写逻辑
- 状态混乱
正确状态:
组件清晰
结构简单
职责单一
十三、常见错误总结
1、UI 写逻辑
2、UI 直接改状态
3、不拆组件
4、嵌套过深
5、UI 和业务状态混用
总结
鸿蒙游戏 UI 设计的核心:
UI 只展示
状态来自 Store
组件必须拆
层级要清晰
在 HarmonyOS 的 ArkUI 架构中,这种设计带来的不是“代码整洁”,而是:
从“写页面”,升级为“设计 UI 系统”。
最后:
UI 一旦乱了,后面所有开发都会变慢;UI 一旦清晰,整个项目都会加速。
更多推荐
所有评论(0)