当前位置: 首页 > news >正文

鸿蒙游戏 UI 怎么设计才不乱?

网罗开发(小红书、快手、视频号同名)

大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。


文章目录

    • 引言
    • 一、先说结论
    • 二、最常见的“乱 UI”写法
      • 一个页面写完一切
    • 三、第一步:UI 只做“展示”
      • UI 写逻辑
      • 正确
    • 四、第二步:状态只来自 Store
      • 页面维护状态
      • 正确
    • 五、第三步:组件拆分
      • 巨型 UI
      • 拆组件
      • 示例
    • 六、第四步:组件分层
      • 推荐分层:
      • 示例
    • 七、第五步:避免深层嵌套
      • 深层嵌套
      • 拆出去
    • 八、第六步:UI 状态分离
      • 单独 UI Store
      • UI 使用
    • 九、第七步:状态驱动 UI
      • 示例
    • 十、第八步:UI 与多端适配
      • 写死布局
      • 响应式
    • 十一、最终 UI 结构
      • 页面代码
    • 十二、判断 UI 是否“健康”
      • 有这些问题:
      • 正确状态:
    • 十三、常见错误总结
    • 总结

引言

很多人刚开始用 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

页面维护状态

@Statescore:number=0

正确

@Statestate=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@Componentstruct GamePage{@Statestate=gameStore.statebuild(){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 一旦清晰,整个项目都会加速。

http://www.jsqmd.com/news/651213/

相关文章:

  • RepDistiller核心原理深度解析:对比表示蒸馏(CRD)如何超越传统方法
  • 从天气预报接口到RESTful API测试:手把手用C# HttpClient造一个‘万能’HTTP调试工具
  • 7.【UPF】UPF Power Shutoff(UPF电源关断)
  • 别再死记硬背公式了!用Python的PuLP库手把手教你推导线性规划对偶问题
  • 去标签化无感定位技术突破,黎阳之光重构空间定位技术路径
  • 从构建到编译:CMake、Make、MinGW、Clang、LLVM、GCC、MSVC的生态位与协作全景
  • Tmux:终端复用器的基本使用(三)
  • 如何解决Blender相机动画的僵硬感?Camera Shakify插件深度解析
  • PX4结合YOLO实现仿真环境下的动态目标检测
  • 手把手教你用Python实现简易视线追踪系统(基于MPIIGaze数据集)
  • WechatBakTool:微信聊天记录备份恢复的终极解决方案
  • 最新感知算法论文分析:RaCFormer 如何提升雷达相机 3D 目标检测性能?
  • 从数据到发现:如何利用Materials Project数据库加速你的新材料研究?
  • Innovus实战:从Tap Cell到Spare Cell,手把手教你搞定数字后端那些‘不起眼’的物理单元
  • 如何使用Poem框架MCP服务器构建高效AI工具集成平台
  • STM32 HAL库实战:1.3寸OLED屏驱动全解析(附软件IIC避坑指南)
  • Android数据管理终极教程:Coursera-android教你5种存储方案
  • 从一次通话失败说起:深入排查CSFB信令中的那些‘隐藏’配置项(附参数详解)
  • 如何永久保存微信聊天记录:WeChatMsg完整备份指南让你的珍贵记忆永不丢失
  • 三步解锁QQ音乐加密音频:qmcdump让你的音乐随处可听
  • 深入解析PowerPC P2040的启动机制与DPAA架构优化
  • 告别Keil破解!用STM32CubeIDE + HAL库点亮你的第一颗LED(STM32F103C8T6保姆级教程)
  • ESP32开发实战:Vscode+PlatformIO与Arduino第三方库管理机制深度对比
  • 融合混沌初始化与自适应权重的PSO算法在机械臂时间最优轨迹规划中的应用
  • 告别版本冲突:基于Python3.9虚拟环境精准部署numpy、tensorflow与matplotlib兼容组合
  • 【STM32H743IIT6】引脚复用全解析:从数据手册图表到实战配置
  • 【ADRC自适应模糊控制】移动机器人轨迹跟踪 MATLAB源码
  • OpenIPC固件在君正T31ZX平台上的烧录问题深度解析
  • 【2026年最新600套毕设项目分享】智慧旅游平台开发微信小程序(30073)
  • 信捷XD六轴标准程序拆解实录