HarmonyOS应用开发实战:猫猫大作战-模运算条件样式、三元表达式样式、enum 映射色、等级色函数四种套路

📅 2026/7/27 23:58:27
HarmonyOS应用开发实战:猫猫大作战-模运算条件样式、三元表达式样式、enum 映射色、等级色函数四种套路
前言上一篇我们用双层ForEach把 5×8 棋盘网格渲出来但每格背景色写的是(rowcol)%2 0 ? #F0F4F8 : #E6EDF3——这个「模运算条件样式」一眼看似简单实则是 ArkUI 响应式样式的核心套路三元表达式根据数据动态返回样式值。这种套路在棋盘色、状态色、等级色、性别色等场景反复出现。本篇以「猫猫大作战」棋盘隔行变色为锚点把模运算条件样式、三元表达式样式、enum 映射色、等级色函数四种套路讲透。读完本篇你将能独立写出棋盘格变色、等级色映射、状态色切换、条件圆角四种动态样式。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–13 篇。一、场景拆解棋盘色三元表达式回顾GameView第 1 层棋盘背景// 来源entry/src/main/ets/pages/Index.ets GameView() 棋盘格 Stack() { Text().fontSize(20) } .width(${100 / COLS}%).height(${100 / ROWS}%) .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3)核心.backgroundColor(...)的参数是一个三元表达式根据(rowcol)%2的奇偶性动态返回浅色或深色。二、三元表达式在样式中的合法位ArkUI 的属性方法.fontSize/.backgroundColor/.borderRadius等接受任意返回合法类型的表达式——包括三元、函数调用、常量。2.1 三元表达式样式.backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3) .fontSize(isTitle ? 20 : 14) .borderRadius(isCard ? 12 : 0) .fontColor(isActive ? #2ECC71 : #95A5A6)语法条件 ? 真值 : 假值。条件为true返回真值否则返回假值。2.2 嵌套三元多条件.backgroundColor( row 0 ? #FFC107 : // 第 0 行黄预警行 row 1 ? #E74C3C : // 第 1 行红危险行 row 2 ? #FFFFFF : // 第 2 行白安全行 #F8F9FA // 其余浅灰 )嵌套三元用于多条件分支——但超过 3 层可读性崩应改用函数第 4 节讲。2.3 三元 vs if/else// ✅ 三元在属性参数里合法 .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3) // ❌ if/else不能写在属性参数里 .backgroundColor(if (cond) { #F0F4F8 } else { #E6EDF3 }) // 语法错关键ArkUI 属性参数里只能用三元不能用 if/else——if是语句不是表达式没有返回值。三、模运算的四种棋盘色套路3.1(rowcol)%2棋盘格本项目(row col) % 2 0 ? #F0F4F8 : #E6EDF3色分布相邻格永远异色经典棋盘。行\列01230浅深浅深1深浅深浅2浅深浅深3.2row%2行间变色row % 2 0 ? #F8F9FA : #FFFFFF色分布相邻行异色同行同色。适合列表项变色。3.3col%2列间变色col % 2 0 ? #F8F9FA : #FFFFFF色分布相邻列异色同列同色。适合横向卡片变色。3.4(row*2col)%3三色循环[(row * 2 col) % 3, #FFC107, #FF9800, #E74C3C] // 伪代码实际用函数色分布三色循环视觉更丰富但易花慎用。四、enum 等级色映射实战打开GameTypes.ets猫咪有 6 级export enum CatLevel { LEVEL_1, // 0 LEVEL_2, // 1 LEVEL_3, // 2 LEVEL_4, // 3 LEVEL_5, // 4 LEVEL_6 // 5 }每级对应一个颜色渲染时要根据cat.level返回对应色。嵌套三元写 6 层就崩应改用函数 switchgetCatColor(level: CatLevel): string { switch (level) { case CatLevel.LEVEL_1: return #FFC107 // 黄 case CatLevel.LEVEL_2: return #FF9800 // 橙 case CatLevel.LEVEL_3: return #E74C3C // 红 case CatLevel.LEVEL_4: return #9B59B6 // 紫 case CatLevel.LEVEL_5: return #2ECC71 // 绿 case CatLevel.LEVEL_6: return #3498DB // 蓝 default: return #FFC107 } } // 使用 Text(this.getCatEmoji(cat.level)) .fontSize(30) .backgroundColor(this.getCatColor(cat.level))4.1 Record 映射表替代 switchconst CAT_COLOR: Recordnumber, string { [CatLevel.LEVEL_1]: #FFC107, [CatLevel.LEVEL_2]: #FF9800, [CatLevel.LEVEL_3]: #E74C3C, [CatLevel.LEVEL_4]: #9B59B6, [CatLevel.LEVEL_5]: #2ECC71, [CatLevel.LEVEL_6]: #3498DB } getCatColor(level: CatLevel): string { return CAT_COLOR[level] ?? #FFC107 // ?? 防空 }Record 映射表优势O(1) 查询比 switch O(n) 快。数据驱动颜色改一处即可不动函数。易扩展加级只需加一行。提示ArkTS 严格模式禁anyRecordK, V是真正的字典映射类型替代 JS 的{}动态对象。本系列第 115 篇会专讲Record。4.2 资源引用替代硬编码色const CAT_COLOR: Recordnumber, Resource { [CatLevel.LEVEL_1]: $r(app.color.cat_level_1), [CatLevel.LEVEL_2]: $r(app.color.cat_level_2), // ... }用$r(app.color.xxx)资源引用替代#FFC107硬编码——暗色模式切换自动适配。本系列第 28 篇会专讲暗色模式。五、状态色切换实战GameState也有色映射getGameStateColor(state: GameState): string { switch (state) { case GameState.IDLE: return #95A5A6 // 灰待机 case GameState.PLAYING: return #2ECC71 // 绿游玩 case GameState.PAUSED: return #FFC107 // 黄暂停 case GameState.GAME_OVER: return #E74C3C // 红结束 default: return #95A5A6 } } // 使用状态指示器 Circle({ width: 12, height: 12 }).fillColor(this.getGameStateColor(this.gameState))状态色语义状态色语义IDLE灰静默PLAYING绿活跃PAUSED黄等待GAME_OVER红警告六、条件圆角实战圆角也能用三元动态控// 棋盘格方角 Stack() { /* ... */ } .borderRadius(0) // 棋子圆角 Text(this.getCatEmoji(cat.level)) .borderRadius(cat.level 5 ? 50 : 12) // 高级猫咪更圆5 级用 50近圆 // 卡片中圆角 Column() { /* ... */ } .borderRadius(isModal ? 24 : 12) // 模态卡片更圆条件圆角套路根据数据动态控圆角让视觉语义随状态变化。七、完整代码四种动态样式对比7.1 棋盘色三元表达式Stack() { Text().fontSize(20) } .width(${100 / COLS}%).height(${100 / ROWS}%) .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3)7.2 等级色函数 switchgetCatColor(level: CatLevel): string { switch (level) { case CatLevel.LEVEL_1: return #FFC107 case CatLevel.LEVEL_2: return #FF9800 case CatLevel.LEVEL_3: return #E74C3C case CatLevel.LEVEL_4: return #9B59B6 case CatLevel.LEVEL_5: return #2ECC71 case CatLevel.LEVEL_6: return #3498DB default: return #FFC107 } } Text(this.getCatEmoji(cat.level)) .fontSize(30) .backgroundColor(this.getCatColor(cat.level)) .borderRadius(8)7.3 状态色Record 映射表const STATE_COLOR: Recordnumber, string { [GameState.IDLE]: #95A5A6, [GameState.PLAYING]: #2ECC71, [GameState.PAUSED]: #FFC107, [GameState.GAME_OVER]: #E74C3C } getGameStateColor(state: GameState): string { return STATE_COLOR[state] ?? #95A5A6 } Circle({ width: 12, height: 12 }).fillColor(this.getGameStateColor(this.gameState))7.4 条件圆角三元嵌套Text(this.getCatEmoji(cat.level)) .fontSize(30) .borderRadius(cat.level 5 ? 50 : 12) // 5 级近圆其余小圆角八、调试技巧动态样式怎么调console.info打色值Builder 里加console.info(color, this.getCatColor(cat.level))追实际渲染色。临时固定色验证把三元临时改成固定#F00红看所有格是否都红——验证表达式是否被调用。密钥冲突排查格子少几个查(rowcol)%2是否依赖了重复的 row/col 值。真机看色预览器渲染接近真机但某些色相可能因屏密度差异以真机为准。九、性能与最佳实践三元表达式比函数调用快简单 2 分支用三元避免函数调用开销。复杂分支用函数 switch/Record超 3 分支别嵌套三元可读性崩。Record 映射表 O(1) 查询比 switch O(n) 快大数据量必用。资源引用替硬编码色$r(app.color.xxx)支持暗色模式硬编码不支持。总结本篇我们从棋盘隔行变色切入掌握三元表达式条件样式、模运算四种棋盘色套路、enum 等级色映射switch/Record、状态色切换、条件圆角五大要点并给出了四种动态样式的完整代码。核心要点属性参数用三元非 if/else简单 2 分支用三元复杂分支用函数 Record 映射资源引用替硬编码。下一篇我们将继续游戏页拆解猫咪渲染的 Emoji Text 与圆形背景。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源「猫猫大作战」项目源码本仓库entry/src/main/ets/pages/Index.etsForEach 循环渲染官方指南文本显示 (Text/Span) 官方指南Shape 容器官方指南开源鸿蒙跨平台社区HarmonyOS 开发者官方文档首页系列索引本仓库articles/INDEX.md