news 2026/7/28 12:26:50

HarmonyOS应用开发实战:猫猫大作战-Badge 的基本用法、位置与样式定制、与 Stack 手搓的取舍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS应用开发实战:猫猫大作战-Badge 的基本用法、位置与样式定制、与 Stack 手搓的取舍

前言

游戏里经常见到这种提示——「最高分 NEW 标」「未读消息红点」「活动倒计时角标」。这些挂在组件右上角的小标记,HarmonyOS 提供了Badge组件一行搞定,不用自己用Stack叠红点。

本篇以「猫猫大作战」主菜单最高分徽章加 NEW 标为锚点,把 Badge 的基本用法位置与样式定制与 Stack 手搓的取舍三大要点讲透。

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

一、场景拆解:最高分 NEW 角标

回顾「猫猫大作战」主菜单最高分行(第 8 篇):

// 来源:entry/src/main/ets/pages/Index.ets MainMenuView() if (this.highScore > 0) { Row() { Text('🏆 最高分: ').fontSize(16).fontColor('#F1C40F') Text(this.highScore.toString()).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#F1C40F') }.margin({ bottom: 32 }) }

现在想加个「NEW」角标——用户首次破纪录时显示,提示「这是新纪录」。用 Badge 包住整个 Row:

Badge({ count: 0, position: BadgePosition.RightTop, style: { fontSize: 10, badgeSize: 28, badgeColor: '#E74C3C' } }) { // 被标记的内容 Row() { Text('🏆 最高分: ...'); } }

关键经验Badge 是「容器型」组件——它包裹目标内容,在指定位置渲染角标。

二、Badge 的两种模式

2.1 数字角标(count)

Badge({ count: 5, // 显示数字 5 position: BadgePosition.RightTop, // 右上角 style: { fontSize: 10, badgeSize: 28, badgeColor: '#E74C3C' } }) { Image($r('app.media.msg')) // 被标记的消息图标 }

count 行为

count 值显示
0不显示角标
1–99显示数字
≥ 100显示「99+」

2.2 文本角标(value)

Badge({ value: 'NEW', // 显示文本「NEW」 position: BadgePosition.RightTop, style: { fontSize: 10, badgeSize: 28, badgeColor: '#E74C3C' } }) { Row() { Text('🏆 最高分: 99') } }

value 行为

value 值显示
空字符串不显示角标
‘NEW’显示「NEW」
‘HOT’显示「HOT」

实战经验数字用 count,文本用 value——不能同时设,同时设以 value 为准。

2.3 position 位置

position: BadgePosition.RightTop // 右上(最常用) position: BadgePosition.Right // 右侧垂直居中
位置适用
RightTop图标右上红点、NEW 角标
Right列表项右侧「未读 5」标记

三、用 Badge 改造最高分行

3.1 加 NEW 角标

@Builder MainMenuView() { Column() { Spacer().height('15%') Text('🐱').fontSize(72).margin({ bottom: 8 }) Text('猫猫大作战').fontSize(36).fontWeight(FontWeight.Bold).fontColor('#2C3E50').margin({ bottom: 8 }) Text('合并进化 · 策略消除').fontSize(16).fontColor('#95A5A6').margin({ bottom: 48 }) // 最高分(Badge 包裹,加 NEW 角标) if (this.highScore > 0) { Badge({ value: this.isNewRecord ? 'NEW' : '', // 新纪录显示 NEW position: BadgePosition.RightTop, style: { fontSize: 10, badgeSize: 28, badgeColor: '#E74C3C', textColor: '#FFFFFF' } }) { Row() { Text('🏆 最高分: ').fontSize(16).fontColor('#F1C40F') Text(this.highScore.toString()).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#F1C40F') } .margin({ bottom: 32 }) } } // 开始游戏按钮 Button('开始游戏') .width('70%').height(56) .fontSize(20).fontWeight(FontWeight.Bold) .fontColor('#FFFFFF').backgroundColor('#2ECC71') .borderRadius(28) .shadow({ radius: 8, color: 'rgba(46, 204, 113, 0.4)', offsetY: 4 }) .onClick(() => { this.startGame(); }) Spacer().height(24) // 规则面板(第 25 篇) Scroll() { /* ... */ }.height(180) Spacer() } .width('100%').height('100%') .linearGradient({ direction: GradientDirection.Bottom, colors: [['#E8F4F8', 0.0], ['#D6EEF5', 0.5], ['#C9E8F2', 1.0]] }) .alignItems(HorizontalAlign.Center) }

3.2 isNewRecord 状态控制

@State isNewRecord: boolean = false; endGame() { this.gameState = GameState.GAME_OVER; if (this.score > this.highScore) { this.highScore = this.score; this.isNewRecord = true; // 标记新纪录 } this.clearTimers(); } // 用户回到主菜单后,3 秒自动隐藏 NEW 角标 startGame() { if (this.isNewRecord) { setTimeout(() => { this.isNewRecord = false; }, 3000); } /* ... */ }

执行流程

  1. 破纪录 →isNewRecord = true→ Badge 显示「NEW」。
  2. 回主菜单看到「🏆 最高分: 99 [NEW]」。
  3. 3 秒后isNewRecord = false→ Badge value 变空 → 角标消失。

四、style 样式定制

4.1 完整 style 参数

style: { fontSize: 10, // 角标文字字号 badgeSize: 28, // 角标直径(圆形) badgeColor: '#E74C3C', // 角标背景色 textColor: '#FFFFFF', // 角标文字色 borderColor: '#FFFFFF', // 角标边框色 borderWidth: 1 // 角标边框宽 }
参数作用默认
fontSize文字字号10
badgeSize角标圆形直径16
badgeColor背景色红色
textColor文字色白色
borderColor边框色
borderWidth边框宽0

4.2 不同场景的 style 配置

场景badgeSizebadgeColorfontSize
未读消息红点8#E74C3C8
未读数字角标20#E74C3C12
NEW 角标28#E74C3C10
HOT 角标32#F39C1211
倒计时角标36#2ECC7110

实战经验角标文字 ≤ 3 字符用 badgeSize 28,4+ 字符用 32+——否则文字溢出角标圆形。

五、Badge vs Stack 手搓红点

5.1 Stack 手搓红点

Stack({ alignContent: Alignment.TopEnd }) { Image($r('app.media.msg')) Text('5') .fontSize(10).fontColor('#FFFFFF') .backgroundColor('#E74C3C') .borderRadius(10) .padding(2) .margin({ top: -4, right: -4 }) } .width(40).height(40)

5.2 Badge 简化版

Badge({ count: 5, position: BadgePosition.RightTop, style: { fontSize: 10, badgeSize: 20, badgeColor: '#E74C3C' } }) { Image($r('app.media.msg')) } .width(40).height(40)

5.3 取舍

维度BadgeStack 手搓
代码量
可定制性中(固定 style 参数)高(任意属性)
99+ 自动转换❌ 要自己写
复杂动效(呼吸/弹跳)

实战经验标准角标用 Badge——99+ 转换、位置对齐都内置;要动效或异形角标用 Stack 手搓

六、踩坑提示

6.1 Badge 包裹的组件没设尺寸

// ❌ 错误:Row 没 width,Badge 角标位置漂 Badge({ value: 'NEW', position: BadgePosition.RightTop }) { Row() { Text('...') } // wrap_content,位置不定 } // ✅ 正确:给被包裹组件设尺寸,或用 padding 固定 Badge({ value: 'NEW', position: BadgePosition.RightTop }) { Row() { Text('...') }.width(120) }

6.2 count 与 value 同时设

// ⚠️ 同时设,value 优先,count 被忽略 Badge({ count: 5, value: 'NEW' }) { /* ... */ } // 显示「NEW」,不显示 5

6.3 Badge 嵌套 Badge

// ❌ 错误:嵌套 Badge,角标重叠混乱 Badge({ count: 1 }) { Badge({ count: 2 }) { Image() } } // ✅ 正确:只包一层 Badge({ count: 2 }) { Image() }

七、性能与最佳实践

  1. 标准角标用 Badge——99+ 自动转换、位置对齐内置。
  2. 数字用 count,文本用 value——别同时设。
  3. 被包裹组件设固定尺寸——避免角标位置漂移。
  4. 要动效或异形角标用 Stack 手搓——Badge 不支持自定义动效。
  5. 角标文字 ≤ 3 字符用 badgeSize 28——否则文字溢出。

总结

本篇我们从 Badge 角标切入,掌握了两种模式(count 数字 / value 文本)position 位置与 style 样式定制与 Stack 手搓的取舍三大要点,并给出了最高分 NEW 角标完整代码。核心要点:Badge 是容器型组件;count 自动 99+;要动效用 Stack 手搓

下一篇我们将拆解 Image 资源引用——$r 与 $rawfile 的区别。

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


相关资源:

  • 「猫猫大作战」项目源码:本仓库entry/src/main/ets/pages/Index.ets
  • Badge 角标组件官方指南
  • BadgePosition 位置枚举官方参考
  • ArkUI 信息标记最佳实践
  • 开源鸿蒙跨平台社区
  • HarmonyOS 开发者官方文档首页
  • 系列索引:本仓库articles/INDEX.md
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 12:26:42

HarmonyOS应用开发实战:猫猫大作战-Swiper 的声明式用法、控制器操作、引导页完整实现以及与应用启动流程的结合

前言 在应用首次启动时,新手引导页通过轮播展示应用的核心功能,帮助用户快速上手。HarmonyOS 的 Swiper 组件提供了声明式的轮播容器,支持循环滑动、自动播放、自定义指示器、切换动画等能力。 本文以「猫猫大作战」的新手引导页为锚点&…

作者头像 李华
网站建设 2026/7/28 12:23:17

构网型逆变器稳定性分析与Matlab建模实践

1. 项目概述:构网型逆变器稳定性研究的工程价值 构网型逆变器(Grid-Forming Inverter, GFMI)作为新能源电力系统的核心接口设备,其稳定性直接关系到微电网和分布式能源系统的可靠运行。不同于传统跟网型逆变器,GFMI需要自主建立电网电压和频率…

作者头像 李华
网站建设 2026/7/28 12:22:09

Java后端高效学习路径:从JVM到Spring生态,构建闭环知识体系

最近在辅导几位准备秋招的学弟学妹,发现一个普遍现象:大家手头资料很多,Java基础、JVM、MySQL、Spring全家桶、八股文、场景题……但面对海量信息,却不知道如何系统性地学习和提升,感觉每天都在“低水平重复”。结合我自己的上岸经验和近期面试官的反馈,我总结了一套当前…

作者头像 李华
网站建设 2026/7/28 12:21:05

物联网设备低功耗电源管理方案与NBM7100A应用解析

1. 项目背景与核心挑战在物联网设备设计中,初级电池(如CR2032纽扣电池)的续航能力一直是工程师面临的核心难题。这类电池通常具有以下特性:不可充电设计,一次性使用容量有限(典型CR2032约220mAh&#xff09…

作者头像 李华
网站建设 2026/7/28 12:20:26

物联网安全解决方案:SE050芯片与PIC18F96J65集成指南

1. 物联网安全现状与SE050芯片的定位在万物互联的时代,物联网设备数量呈现指数级增长。根据最新行业统计,全球活跃物联网设备已突破150亿台,预计2025年将超过270亿台。然而与之相伴的是日益严峻的安全威胁——2023年物联网设备遭受的网络攻击…

作者头像 李华