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

HarmonyOS应用开发实战:猫猫大作战-`displayPriority` 的优先级机制、隐藏触发条件、与 layoutWeight 搭配

前言

前面我们用layoutWeight让 HUD 三栏按 2:1:2 比例分宽——屏宽变化时各栏同比例缩放。但有个新问题:窄屏(折叠屏合屏、小尺寸手机)时,连击栏被挤成一条缝,文字溢出截断。我们想要的是:宽屏三栏全显示,窄屏自动隐藏低优先级的连击栏,只留得分和时间。

HarmonyOS 提供了displayPriority优先级布局——给每个子组件设一个优先级,容器空间不足时自动隐藏低优先级组件。本篇以「猫猫大作战」HUD 窄屏适配为锚点,把displayPriority优先级机制隐藏触发条件与 layoutWeight 搭配三大要点讲透。

提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–23 篇。本篇是布局进阶的第四篇。

一、场景拆解:HUD 窄屏适配

回顾「猫猫大作战」HUD(第 23 篇):

// 来源:entry/src/main/ets/pages/Index.ets GameHUD() 改造版 Row() { Column() { Text('得分'); Text(score) } .layoutWeight(2) Row() { Text(`🔥 x${combo}`) } .layoutWeight(1) Column() { Text('时间'); Text(time) } .layoutWeight(2) } .width('100%')

痛点

屏宽得分栏连击栏时间栏视觉
360vp(宽屏)144vp72vp144vp✅ 三栏舒服
280vp(窄屏)112vp56vp112vp❌ 连击栏 56vp 文字溢出
200vp(超窄)80vp40vp80vp❌ 连击栏 40vp 几乎看不见

我们想要:屏宽 < 300vp 时自动隐藏连击栏,得分和时间平分宽度

displayPriority的解法

Row() { Column() { /* 得分 */ }.layoutWeight(2).displayPriority(1) Row() { /* 连击 */ }.layoutWeight(1).displayPriority(2) // 优先级低,先被隐藏 Column() { /* 时间 */ }.layoutWeight(2).displayPriority(1) } .width('100%')

关键经验displayPriority值越大优先级越低,容器空间不足时先隐藏低优先级(高数值)组件

二、displayPriority 优先级机制

2.1 优先级数值含义

.displayPriority(N) // N 是正整数
N 值含义隐藏顺序
1最高优先级最后被隐藏
2次高优先级第 2 个被隐藏
3中等优先级第 3 个被隐藏
N优先级随 N 增大而降低

规则:容器空间不足时,按displayPriority从大到小依次隐藏;同优先级的组件一起隐藏或一起显示。

2.2 隐藏触发条件

displayPriority不是「屏宽小于某个值就隐藏」,而是更智能的自适应隐藏

容器宽度 - 所有组件最小宽度之和 < 0 → 开始隐藏低优先级组件

最小宽度来自组件的width、内容宽度、constraintSize.minWidth等。

举例(HUD 三栏):

组件最小宽度displayPriority
得分栏100vp1
连击栏60vp2
时间栏100vp1

容器宽度变化时的行为:

容器宽度最小宽度和是否够行为
360vp260vp三栏全显示
280vp260vp✅ 勉强三栏全显示(各栏接近最小宽)
200vp260vp❌ 差 60vp隐藏连击栏(省 60vp),剩得分+时间

2.3 与 layoutWeight 的关系

Row() { Column() { /* 得分 */ }.layoutWeight(2).displayPriority(1) Row() { /* 连击 */ }.layoutWeight(1).displayPriority(2) Column() { /* 时间 */ }.layoutWeight(2).displayPriority(1) } .width('100%')

执行顺序

  1. 先评估displayPriority——决定哪些组件显示、哪些隐藏。
  2. 再算layoutWeight——对显示的组件按权重分宽。

关键经验displayPriority决定「显示与否」,layoutWeight决定「显示后分多少宽」——两者协同工作。

三、用 displayPriority 改造 HUD

3.1 改造为窄屏自适应隐藏

@Builder GameHUD() { Row() { // 左:得分(最高优先级,永远显示) Column() { Text('得分') .fontSize(11) .fontColor('#95A5A6') Text(this.score.toString()) .fontSize(22) .fontWeight(FontWeight.Bold) .fontColor('#2C3E50') } .layoutWeight(2) .displayPriority(1) // 优先级 1:最后被隐藏 .alignItems(HorizontalAlign.Start) // 中:连击(低优先级,窄屏先隐藏) if (this.combo.count > 1) { Row() { Text(`🔥 x${this.combo.multiplier}`) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#E74C3C') } .layoutWeight(1) .displayPriority(2) // 优先级 2:窄屏先隐藏 .justifyContent(FlexAlign.Center) .padding({ left: 8, right: 8, top: 4, bottom: 4 }) .backgroundColor('rgba(231, 76, 60, 0.1)') .borderRadius(16) } // 右:时间(最高优先级,永远显示) Column() { Text('时间') .fontSize(11) .fontColor('#95A5A6') Text(this.formatTime(this.gameTime)) .fontSize(18) .fontWeight(FontWeight.Medium) .fontColor('#2C3E50') } .layoutWeight(2) .displayPriority(1) // 优先级 1:最后被隐藏 .alignItems(HorizontalAlign.End) } .width('100%') .padding({ left: 20, right: 20, top: 12, bottom: 8 }) }

改造效果

屏宽得分连击时间行为
≥ 300vp2/51/52/5✅ 三栏全显示
< 300vp1/2❌隐藏1/2✅ 连击隐藏,得分时间平分

3.2 关键:连击栏 displayPriority(2)

.displayPriority(2) // 数值大 = 优先级低 = 先被隐藏

逻辑:连击是「锦上添花」信息(连击数 + 倍率),得分和时间是「必须可见」的核心信息。窄屏时优先隐藏连击。

3.3 隐藏后的宽度重分配

连击栏隐藏后,Row 重新计算layoutWeight

// 隐藏前:2 + 1 + 2 = 5,得分 2/5、连击 1/5、时间 2/5 // 隐藏后:2 + 2 = 4,得分 2/4=1/2、时间 2/4=1/2

得分和时间各占 50% 宽度,布局自动重平衡。

四、displayPriority 多组件场景

4.1 场景:游戏结束弹窗 4 个统计项

// 来源:entry/src/main/ets/pages/Index.ets GameOverOverlay() Row() { this.StatItem('时间', this.formatTime(this.gameTime)) this.StatItem('合并', `${this.mergeCount}次`) this.StatItem('最高连击', `x${this.maxCombo}`) } .width('100%') .justifyContent(FlexAlign.SpaceEvenly)

3 个统计项平铺,窄屏时文字会重叠。用displayPriority让低优先级的「最高连击」先隐藏:

Row() { this.StatItem('时间', this.formatTime(this.gameTime)) .displayPriority(1) // 必须:时间永远显示 this.StatItem('合并', `${this.mergeCount}次`) .displayPriority(2) // 次要:窄屏第 2 个隐藏 this.StatItem('最高连击', `x${this.maxCombo}`) .displayPriority(3) // 最次要:窄屏第 1 个隐藏 } .width('100%') .justifyContent(FlexAlign.SpaceEvenly)

窄屏隐藏顺序

屏宽时间合并最高连击行为
宽屏全显示
中屏隐藏最高连击
窄屏隐藏合并 + 最高连击

4.2 同优先级组件

Row() { Text('A').displayPriority(1) Text('B').displayPriority(1) // 与 A 同优先级 Text('C').displayPriority(2) // 低优先级 } // 窄屏时 C 先隐藏;再窄时 A、B 一起隐藏

关键经验同优先级组件「同生共死」——要么一起显示,要么一起隐藏。

五、displayPriority vs visibility vs if/else

ArkUI 有三种「隐藏组件」的方式,容易混淆:

5.1 三者对比

方式触发占布局空间适合
displayPriority容器空间不足自动触发隐藏后不占,其他组件重分配自适应窄屏
visibility(Visibility.Hidden)开发者手动设隐藏后仍占空间条件占位
if/else条件渲染隐藏后不占,但需重新渲染状态切换

5.2 场景对照

// 场景 1:窄屏自动隐藏连击 → displayPriority Row() { Column().displayPriority(1) Row().displayPriority(2) // 窄屏自动隐藏 Column().displayPriority(1) } // 场景 2:加载时占位但不显示 → visibility Text('加载中...').visibility(this.isLoading ? Visibility.Visible : Visibility.Hidden) // 场景 3:登录态切换不同界面 → if/else if (this.isLoggedIn) { MainPage() } else { LoginPage() }

关键经验displayPriority是唯一的「自适应」隐藏——其他两种都是开发者显式控制。

5.3 displayPriority 的局限

displayPriority只能「隐藏」,不能「折叠样式」——比如窄屏时想把三栏改成纵向排列,displayPriority做不到,得用响应式布局(GridRow/GridCol,本系列第 88 篇会讲)。

六、完整代码:displayPriority 版 HUD

// 改造版:用 displayPriority 让窄屏自动隐藏连击栏 @Builder GameHUD() { Row() { // 左:得分(最高优先级,永远显示) Column() { Text('得分') .fontSize(11) .fontColor('#95A5A6') Text(this.score.toString()) .fontSize(22) .fontWeight(FontWeight.Bold) .fontColor('#2C3E50') } .layoutWeight(2) .displayPriority(1) .alignItems(HorizontalAlign.Start) // 中:连击(低优先级,窄屏先隐藏) if (this.combo.count > 1) { Row() { Text(`🔥 x${this.combo.multiplier}`) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#E74C3C') } .layoutWeight(1) .displayPriority(2) .justifyContent(FlexAlign.Center) .padding({ left: 8, right: 8, top: 4, bottom: 4 }) .backgroundColor('rgba(231, 76, 60, 0.1)') .borderRadius(16) } // 右:时间(最高优先级,永远显示) Column() { Text('时间') .fontSize(11) .fontColor('#95A5A6') Text(this.formatTime(this.gameTime)) .fontSize(18) .fontWeight(FontWeight.Medium) .fontColor('#2C3E50') } .layoutWeight(2) .displayPriority(1) .alignItems(HorizontalAlign.End) } .width('100%') .padding({ left: 20, right: 20, top: 12, bottom: 8 }) }

七、踩坑提示

7.1 displayPriority 与 width 冲突

// ❌ 错误:固定 width + displayPriority,width 优先,displayPriority 不触发 Text('A').width(80).displayPriority(2) // ✅ 正确:displayPriority 配合 layoutWeight 或不设 width Text('A').layoutWeight(1).displayPriority(2)

7.2 所有组件同 displayPriority

// ⚠️ 全部 displayPriority(1):同优先级,窄屏一起隐藏 Row() { Text('A').displayPriority(1) Text('B').displayPriority(1) Text('C').displayPriority(1) } // 窄屏时 A、B、C 一起消失,HUD 变空白

解法:核心信息设displayPriority(1),次要信息设更高数值。

7.3 displayPriority 不触发

// 现象:屏宽已经很窄,但连击栏还在显示 // 排查:连击栏最小宽度可能很小(文字短),容器空间够,不触发隐藏 // 解法:用 constraintSize 设最小宽度,强制触发 Row().constraintSize({ minWidth: 80 }).displayPriority(2)

八、调试技巧

  1. DevEco 多设备预览:同时看手机/折叠屏/平板预览,验证不同屏宽下的隐藏行为。
  2. 临时加背景色:给每个 displayPriority 组件加不同背景色,看清隐藏顺序。
  3. console.info监屏宽window.on('windowSizeChange')打 log,追屏宽变化与隐藏触发点。

九、性能与最佳实践

  1. 窄屏自适应用displayPriority——比手动 if/else 响应屏宽更优雅。
  2. 核心信息 displayPriority(1),次要信息递增——保证核心永远可见。
  3. displayPriority 配 layoutWeight——隐藏后剩余组件按权重重新分配。
  4. 同优先级组件同生共死——要么一起显示,要么一起隐藏。
  5. 需要重新排列(横→竖)用 GridRow——displayPriority 只能隐藏不能重排。

总结

本篇我们从 displayPriority 切入,掌握了优先级数值含义(大值低优先级先隐藏)隐藏触发条件(容器空间不足时)与 layoutWeight/visibility/if-else 的取舍三大要点,并给出了 displayPriority 版 HUD 完整代码。核心要点:displayPriority 自适应窄屏隐藏;核心信息优先级 1;隐藏后 layoutWeight 重分配

下一篇我们将拆解 Scroller——长内容滚动容器。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • 「猫猫大作战」项目源码:本仓库entry/src/main/ets/pages/Index.ets
  • displayPriority 优先级布局官方指南
  • visibility 显隐控制官方指南
  • 多端布局自适应最佳实践
  • 开源鸿蒙跨平台社区
  • HarmonyOS 开发者官方文档首页
  • 系列索引:本仓库articles/INDEX.md
http://www.jsqmd.com/news/1278054/

相关文章:

  • 华为MetaERP财务共享模块的技术架构与实战解析
  • ChatTTS-ui终极指南:5分钟打造本地文字转语音系统
  • 手机速度突然变慢---------原来只是因为手机发热
  • 2021创客硬件年度盘点:从边缘AI到开发体验的技术演进与选型指南
  • 终极GTA5增强版菜单系统:YimMenuV2架构设计与工程实践深度解析
  • 行空板驱动麦昆Plus:Python智能小车开发全攻略
  • 三个月掌握AI大模型:程序员高效学习路线与实践
  • 如何快速掌握Loop:Mac窗口管理的终极免费工具
  • Genesis World 机器人仿真平台:从零构建物理AI应用的终极指南
  • 怎样高效使用ChatTTS文字转语音工具:新手快速入门手册
  • vLLM 与 SGLang 推理框架性能横评:从原理到实战
  • 战略视角:如何利用GitHub星标历史数据为技术决策提供量化支持
  • Claude Opus版本升级实战:从4.8到5的工程适配指南
  • 基于K210与Mixly的人脸追踪舵机云台:图形化实现AI视觉控制
  • 终端文件传输神器 termscp:5分钟快速安装与完整使用指南
  • Three.js硬编码实战:AI代码生成工具Claude Opus 5成本与质量评测
  • 从零玩转可级联RGB灯带:硬件连接、通信协议与实战调试
  • GTA5增强版终极修改指南:YimMenuV2的5个核心技巧
  • 2026 AI Agent 搜索 Skill 分类选型指南:海外 SaaS、国内方案与开源部署全解析
  • 英雄联盟Akari助手:三步解锁你的游戏超能力,告别繁琐配置的终极指南
  • 终极开源音乐播放器:Spotube如何让你完全掌控自己的音乐体验?
  • 3分钟掌握ncmdump:免费解锁网易云NCM加密音乐的终极方案
  • 大语言模型评估新突破:TrustJudge框架解析与实践
  • Spring Boot高校新生报到系统开发实践
  • USB传感器逆向工程实战:从串口协议破解到自定义上位机开发
  • OpenClaw自动发文系统配置与多平台发布实践
  • 2026-07-28:统计每个顶点的度。用go语言,给你一个 n x n 的二维整数数组,它代表一个无向图的邻接矩阵,包含 n 个编号从 0 到 n-1 的顶点。 矩阵中的值表示两个顶点之间是否有边:
  • 基于Mind+与Python的智能家居数据可视化大屏实战
  • 如何用Goose桌面应用告别命令行:3个核心技巧提升AI助手使用效率
  • 三分钟搞定!免费开源中文字体霞鹜文楷终极安装使用指南