
HarmonyOS 应用 · 寝室投票结果页深度解析isWin 冠军标记与 Stack 占比条项目编号49-dorm-vote 技术栈HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面结果页ProfileTab.ets91 行 系列导航一首页 · 二创建 · 三投票 ·四结果一、ResultItem interfaceisWin 胜出布尔位interface ResultItem { id: number; emoji: string; name: string; votes: number; percent: number; isWin: boolean; }六个字段id是 key 锚点emoji是选项图标name是选项名votes是得票数percent是得票占比isWin是是否胜出的布尔位。isWin是结果页的核心状态字段——驱动 皇冠、票数颜色、占比条颜色三态变化。private results: ResultItem[] [ { id: 1, emoji: , name: 麻辣香锅, votes: 2, percent: 50, isWin: true }, { id: 2, emoji: , name: 黄焖鸡米饭, votes: 1, percent: 25, isWin: false }, { id: 3, emoji: , name: 汉堡炸鸡, votes: 1, percent: 25, isWin: false }, { id: 4, emoji: , name: 披萨意面, votes: 0, percent: 0, isWin: false } ];四个选项麻辣香锅 2 票 50% 胜出、黄焖鸡/汉堡炸鸡各 1 票 25%、披萨 0 票。总票数 4 与投票页3/4 人已投对应——结果页是已结束投票的最终统计。二、页面骨架WinnerCard ResultListbuild() { Column() { this.Header() Scroll() { Column({ space: 14 }) { this.WinnerCard() this.SectionTitle(投票详情) this.ResultList() } .width(100%) .padding({ left: D.pad, right: D.pad, top: 14, bottom: D.pad this.safeBottom 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width(100%).height(100%).backgroundColor(C.bg) }Header 在 Scroll 外固定Scroll 内三块WinnerCard冠军卡 SectionTitle分区标题 ResultList结果列表。与班费统计页的三块图表不同结果页先给结论冠军卡再看明细——投票结果的核心是谁赢了。三、WinnerCard粉色渐变冠军卡Builder WinnerCard() { Column({ space: 10 }) { Text().fontSize(44) Text(麻辣香锅).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#FFFFFF) Text(以 2 票50%胜出).fontSize(13).fontColor(#FFFFFF).opacity(0.9) } .width(100%).padding(24).borderRadius(D.rLg) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) }44 号 20 号加粗白色胜出项 13 号白色半透明以 2 票50%胜出。linearGradient135° 从C.primary#FF6B9D到C.accent#FF9DBA粉色渐变 的组合传递庆祝/胜出的氛围。三行纵向堆叠——图标 → 胜者 → 数据冠军卡是投票结果的颁奖台。四、ResultListisWin 驱动的三态 Stack 占比条Builder ResultList() { Column({ space: 12 }) { ForEach(this.results, (r: ResultItem) { Column({ space: 8 }) { Row({ space: 10 }) { Text(r.emoji).fontSize(22) Text(r.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor(C.text).layoutWeight(1) if (r.isWin) { Text().fontSize(16) } Text(r.votes 票).fontSize(13).fontColor(r.isWin ? C.primary : C.textDim) }.width(100%) Stack({ alignContent: Alignment.Start }) { Row().width(100%).height(10).backgroundColor(C.cardSoft).borderRadius(5) Row().width(r.percent %).height(10) .backgroundColor(r.isWin ? C.primary : C.textDim).borderRadius(5) }.width(100%) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }, (r: ResultItem) r.id.toString()) }.width(100%) }isWin驱动三态变化——皇冠、票数色、占比条色三路分支// 皇冠胜出项显示 if (r.isWin) { Text().fontSize(16) } // 票数颜色主色粉 vs 灰色 .fontColor(r.isWin ? C.primary : C.textDim) // 占比条颜色粉色 vs 灰色 .backgroundColor(r.isWin ? C.primary : C.textDim)胜出项麻辣香锅显示 皇冠 粉色票数 粉色占比条落选项灰色系——冠军的视觉突出与一枝独秀的排序表达。Stack 双层占比条——与班费统计页的 CatChart 同款手法Stack({ alignContent: Alignment.Start }) { // 底层100% 宽浅灰轨道 Row().width(100%).height(10).backgroundColor(C.cardSoft).borderRadius(5) // 上层percent% 宽彩色条 Row().width(r.percent %).height(10).backgroundColor(r.isWin ? C.primary : C.textDim).borderRadius(5) }Alignment.Start让彩色条从左对齐。10px 高度比班费统计页的 8px 粗——结果页的占比条更醒目。50%/25%/25%/0% 的占比直观呈现票数分布。五、跨页数据自洽结果页与投票页的联动麻辣香锅胜出↔ 投票页四个选项之一id: 4 麻辣香锅——结果页与投票页同源总票数 4↔ 投票页3/4 人已投——Demo 中结果页比投票页多 1 票模拟有人后续投票50% 2/4 票↔total: 4人数——占比按总人数计算 胜出标记↔ 首页已结束投票的结果展示——首页查看结果按钮的落地页六、可演进方向方向现状改法收益数据来源静态数组从投票记录动态统计结果随投票更新平票处理仅单冠军平票时并列显示多个 平票场景覆盖投票人明细无显示谁投了这项透明化投票结果分享无生成结果图 分享卡片传播投票结果时间维度无展示投票时间线何时开/关投票过程可追溯结果页是投票的最终呈现——WinnerCard 粉色渐变的颁奖台 ResultList 的isWin驱动三态 Stack 占比条。从条件渲染的 皇冠到双层占比条的叠加技巧每一层都有明确的职责边界。系列导航一首页 · 二创建 · 三投票 ·四结果