☰
鸿蒙原生应用 ArkUI 声明式:签到墙首页连续天数卡与今日活动列表
2026/10/3 11:44:47 网站建设 项目流程

鸿蒙原生应用 ArkUI 声明式:签到墙首页连续天数卡与今日活动列表

App 45「校园签到墙」首页(HomeTab),主题色#FDCB6E黄色(yellow),4 个 Tab 分别为首页(✅)、活动(📅)、签到(📍)、我的(👤)。首页采用"Header + 签到卡 + 活动列表"三区布局——白色单行 Header("签到墙"22 号加粗)+黄色渐变签到卡("7"34 号加粗连续签到天数 + "连续签到(天)" + 右侧"今日已签 2/3" + 白色"去签到"胶囊按钮)+SectionTitle(今日签到活动)+ 4 条活动列表(📚 晨读打卡 / 🏃 晨跑活动 / 🎯 自习室学习 / 🎨 社团活动,每条含 50×50 淡黄圆角图标 + 名称 + ⏰ 时段 · N 人已签 + 已签到/签到双态按钮)。其中"已签到/签到"是可切换的双态按钮(绿灰已签态 vs 黄底白字待签态)。本篇基于45-checkin-wall/entry/src/main/ets/pages/HomeTab.ets(共 97 行)逐段拆解,附 4 张实机截图。

一、整体结构:三区"Header + 签到卡 + 活动列表"布局

首页是"品牌头部 + 签到状态 + 活动清单"的三区布局——3 个 @Builder 块:

build() { Column() { this.Header() Scroll() { Column({ space: 14 }) { this.TodayCard() this.SectionTitle('今日签到活动') this.ActivityList() } .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) }

3 块结构:

  1. Header— 单行品牌头("签到墙"),白底固定
  2. TodayCard— 黄色渐变签到状态卡,展示连续签到天数与今日进度
  3. ActivityList— "今日签到活动" + 4 条活动,每条带签到按钮(已签/待签双态)

首页是系列中最"功能驱动"的首页——没有宣传 Banner、没有内容流,第一屏就是"连续签到 + 去签到",直接把产品核心动作(签到)放在最显眼位置,是工具型产品的首页设计(App 45 定位为"校园签到工具",效率优先于氛围)。

项目源码开源:https://gitee.com/codenestFlow/HarmonyOSHub

二、Header:单行品牌头

Header() { Column() { Text('签到墙').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.text) .width('100%').padding({ top: this.safeTop + 10, left: D.pad, right: D.pad, bottom: 12 }) }.width('100%').backgroundColor(C.card) }

单行 22 号加粗、safeTop + 10避让状态栏、底部 12 内边距、白底全宽。"签到墙"命名直白(一面签到墙,签到活动都在上面),比"签到中心"更形象,也暗示"打卡上墙"的仪式感。

三、TodayCard:连续签到渐变卡

TodayCard() { Row({ space: 16 }) { Column({ space: 4 }) { Text('7').fontSize(34).fontWeight(FontWeight.Bold).fontColor('#FFFFFF') Text('连续签到(天)').fontSize(12).fontColor('#FFFFFF').opacity(0.9) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Column({ space: 6 }) { Text('今日已签 2/3').fontSize(13).fontColor('#FFFFFF').opacity(0.9) Text('去签到').fontSize(13).fontColor(C.primary) .padding({ left: 16, right: 16, top: 7, bottom: 7 }).backgroundColor('#FFFFFF').borderRadius(16) }.alignItems(HorizontalAlign.End) } .width('100%').padding(18).borderRadius(D.rLg) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) }

技术拆解:

  1. 黄色渐变:linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })从#FDCB6E黄渐变到#FDD99A浅黄——系列首次黄色主题,温暖醒目(签到是"每天的小确幸",黄色贴合激励氛围)。
  2. 左数据右动作:左侧"7"34 号加粗(连续签到天数,核心激励数据)+ "连续签到(天)"标签;右侧"今日已签 2/3"(今日进度)+ "去签到"白色胶囊按钮(backgroundColor('#FFFFFF')+ 黄色文字)——白底黄字的反色胶囊在渐变上格外醒目,是卡片的 CTA。
  3. 数据自洽:"7 天"连续签到 ↔ 我的页统计"7 连续签到"(完全一致);"今日已签 2/3" ↔ 首页 4 个活动中 2 个已签(晨读打卡/自习室学习isMine: true)——卡片的每个数字都能在页面/我的页找到出处。
  4. 去签到的跳转:白色胶囊未挂点击事件(纯展示引导)——产品化后点击跳转签到 Tab(📍),与签到页"立即签到"按钮衔接。

四、ActivityList:今日签到活动列表

ActivityList() { Column({ space: 12 }) { ForEach(this.activities, (a: Activity) => { Row({ space: 12 }) { Row() { Text(a.emoji).fontSize(26) } .width(50).height(50).backgroundColor(C.primarySoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center) Column({ space: 4 }) { Text(a.name).fontSize(15).fontWeight(FontWeight.Medium).fontColor(C.text) Text('⏰ ' + a.time + ' · ' + a.checked + ' 人已签').fontSize(12).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Text(a.isMine ? '已签到' : '签到').fontSize(12) .fontColor(a.isMine ? C.ok : '#FFFFFF') .padding({ left: 14, right: 14, top: 7, bottom: 7 }) .backgroundColor(a.isMine ? C.cardSoft : C.primary).borderRadius(D.rSm) .onClick(() => { promptAction.showToast({ message: a.isMine ? '今日已签到' : '签到成功' }); }) } .width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }, (a: Activity) => a.id.toString()) }.width('100%') }

4 个活动(21-26 行):

活动emoji时段已签人数我的状态
晨读打卡📚07:00-08:00128已签到
晨跑活动🏃06:30-07:3086未签
自习室学习🎯全天234已签到
社团活动🎨15:00-17:0045未签

卡片细节:

  1. 图标:50×50 淡黄圆角(primarySoft)方形 + 26 号 emoji——比圆形头像更"工整",契合工具类页面的信息密度。
  2. 信息列:活动名 15 号 Medium +⏰ 时段 · N 人已签12 号浅灰——时间(何时签)+ 人数(多少人签了)双信息,layoutWeight(1)撑开。
  3. 双态按钮:a.isMine ? '已签到' : '签到'——系列首个"按钮双态"交互:
    • 已签到态:绿色文字(C.ok)+ 浅灰底(C.cardSoft)——"已签到"弱化(已完成、无需操作)
    • 待签态:白色文字 + 黄底(C.primary)——"签到"强化(可操作、醒目)
    • 语义对比:已签的"绿字灰底"暗示完成不可再点(点击弹"今日已签到"),待签的"白字黄底"是 CTA(点击弹"签到成功")——状态不同、视觉强弱不同,用户一眼看出"哪些签了、哪些要签"。
  4. 点击反馈:双态各自的 Toast 文案(今日已签到/签到成功)——产品化后点击"签到"应调起真实签到(定位/扫码)并翻转isMine(列表重渲染)。
  5. key:a.id.toString()稳定唯一。

五、跨页数据自洽:签到数据贯穿四页

首页的签到数据与其他 Tab 形成完整闭环:

  • "连续签到 7 天"↔ 我的页统计"7 连续签到"、签到页"本周签到"(周一到周四 ✅ 4 天)——7 天连续 = 本周 4 天 + 上周 3 天,量级自洽。
  • "今日已签 2/3"↔ 首页 2 个已签活动(晨读/自习室)——2/3 的"2"就是列表里 2 个已签。
  • 活动名单↔ 活动页 4 个活动(晨读打卡/晨跑活动/自习室学习/社团活动)完全同名同序——首页是"今日可签清单"、活动页是"活动详情+规则"。
  • "N 人已签"↔ 活动页的积分奖励——人数是签到热度的体现(128 人晨读),积分是签到动机的激励。
  • 我的页"128 累计签到"↔ 晨读 128 人已签的"128"纯属巧合(一个是累计天数、一个是人数),但都强化了"128"这个数字在 App 内的记忆点。

六、实机截图与交互演示

本节结合 4 张实机截图,逐张还原首页的视觉效果与交互过程。

1. 首页首屏:签到卡 + 活动列表

第一张截图是进入 App 45 后的默认首屏:顶部"签到墙"标题;下方黄色渐变签到卡——左侧"7"34 号大数字与"连续签到(天)"、右侧"今日已签 2/3"与白色"去签到"胶囊;再往下是"今日签到活动"与活动列表——📚 晨读打卡(已签到 绿字灰底)、🏃 晨跑活动(签到 黄底白字)、🎯 自习室学习(已签到)、🎨 社团活动(签到)——两种按钮状态同屏对比,用户一眼看清"哪些签了哪些没签"。

2. 点击"已签到":今日已签到 Toast

第二张截图是点击"晨读打卡"的"已签到"(绿字灰底)按钮后的反馈:弹出"今日已签到"Toast——isMine为 true 走已签分支,提示用户"今天已经打过卡了",防止重复签到。

3. 点击"签到":签到成功 Toast

第三张截图是点击"晨跑活动"的"签到"(黄底白字)按钮后的反馈:弹出"签到成功"Toast——isMine为 false 走待签分支,成功签到。双态按钮的分支交互完整,产品化后此处应翻转isMine并重渲染(已签人数 +1)。

4. 首页完整列表:四活动全览

第四张截图是首页的完整列表视图:四个活动全部可见(晨读打卡 已签 / 晨跑活动 待签 / 自习室学习 已签 / 社团活动 待签),"已签 2/3"的进度与列表 2 个已签完全对应。签到卡黄渐变、按钮黄白对比,整页黄色系主题统一醒目。

七、扩展思考:签到系统的激励设计

首页的"连续签到 + 今日进度"是签到系统激励设计的最小骨架,真实产品的激励体系复杂得多:

  1. 连续签到奖励:活动页"连续签到7天获积分奖励"(晨读 50 积分)——连续签到是核心激励(中断归零的损失厌恶驱动每日签到),首页"7"的大数字就是连续性的可视化。
  2. 积分经济学:我的页"860 积分"、签到页"签到成功 +50积分"——签到产出积分、积分可兑换(我的页"积分兑换"菜单),形成"签到 → 积分 → 兑换"的激励闭环。
  3. 勋章体系:我的页勋章卡(🌟 签到新星/🔥 连续7天/💯 百日达人/👑 签到之王)——勋章是成就感的载体,未获得的勋章(💯👑 半透明)是"继续签到"的动力。
  4. 排行榜:活动页"128 人已签"可延伸为"签到排行榜"(本周签到达人 Top10)——社交比较驱动参与。
  5. 提醒推送:每日签到时段推送提醒("晨读时间到,记得打卡 📚")——签到工具的拉活利器。

八、扩展思考:双态按钮的交互设计

首页的"已签到/签到"双态按钮是系列首次"按钮状态切换",其设计原则值得展开:

  1. 状态即语义:已签 = 绿字灰底(弱化、完成态)、待签 = 白字黄底(强化、行动态)——视觉强度与操作优先级严格对应,用户不读文字也能分辨"哪里还能点"。
  2. 点击的防重:已签按钮点击弹"今日已签到"(拦截重复)——防止重复签到的业务规则在 UI 层表达。
  3. 状态翻转:产品化后点击"签到"应isMine = true翻转 + 列表重渲染(@State activities整体重赋值,系列 @State 数组规范)——按钮从黄转绿灰、人数 +1、签到卡"今日已签 2/3"变 3/3,三处状态同步更新是签到闭环的验收点。
  4. 与系列其他状态的对比:App 41 点赞是"点一下变实心"(无业务拦截)、本页已签是"再点提示已签"(有业务拦截)——签到是"每日一次"的稀缺动作,需要防重;点赞是"随时可点"的高频动作,无需防重,动作频次决定防重设计。
  5. 按钮实现:本页按钮用Text实现(轻量、样式自由)——若需要按压态反馈可换Button,当前结构已满足原型需求。

九、开发者视角:首页的调试与验证技巧

  1. 双态按钮的分支测试:分别点击"已签到"(今日已签到)与"签到"(签到成功)两条路径——确认分支判断读取的是同一isMine状态源;再测试"isMine 翻转后按钮样式与 Toast 是否正确切换"。
  2. 签到卡数字的自洽:"7 连续签到"与我的页统计"7"、签到页本周签到(周一到周四 ✅)的核对——修改任一页需同步(系列验收标准)。
  3. 渐变卡的白字可读性:#FDCB6E黄渐变上的白色文字(7/连续签到(天))对比度——黄色较浅,白字需opacity(0.9)层次;真机验证各机型白字清晰。
  4. 长活动名的省略:"⏰ 07:00-08:00 · 128 人已签"这类副信息若活动名超长会换行挤压——maxLines(1)省略或调整布局(当前 4 个活动名均短,无碍)。
  5. 列表状态刷新:若实现"签到 → isMine 翻转",@State activities需整体重赋值(this.activities = this.activities.slice())——系列 @State 数组的经典坑,防漏。

十、FAQ 与一句话总结

Q1:为什么首页没有 Banner 或内容流?签到墙是工具型产品(核心动作是签到),首页第一屏直接给"连续签到 + 去签到 + 今日活动清单",效率优先;App 40/42 的 Banner/内容流是内容型产品的"氛围页",工具型首页应该"开门见山"。产品类型决定首页形态。

Q2:双态按钮的意义是什么?让用户一眼分清"哪些已签、哪些待签"(绿灰=完成、黄底=待做),并防止重复签到(已签点击提示"今日已签到")——状态可视化 + 业务防重双职能。

Q3:"今日已签 2/3"怎么算的?3 = 今日活动总数(4 个中 2 个已签 + 晨跑/社团待签——严格说 4 个活动签 2 个应为 2/4,Demo 的 2/3 是"今日可签的 3 个"口径(社团 15:00-17:00 未开始不计入)——产品化时口径需明确(当日已开始活动为分母)。

Q4:点击"签到"后会发生什么?Demo 弹 Toast。产品化后调起真实签到(定位/扫码,签到页模式)→ 成功翻转isMine+ 人数 +1 + 签到卡进度更新——"签到 → 状态联动"是闭环核心。

Q5:签到为什么需要"连续"概念?连续签到利用"损失厌恶"心理(断签清零)驱动每日签到习惯——"7"天的大数字是连续性成就感的可视化,配合积分/勋章形成完整激励。

一句话总结:首页以"连续签到卡 + 今日活动清单"完成了签到工具的门面。"7"天连续签到的激励数据、白色"去签到"CTA、"已签到/签到"双态按钮(系列首次状态切换)、"今日已签 2/3"与列表的进度自洽——97 行代码,一个让用户"每天想打开打卡"的签到墙首页,也是工具型首页与内容型首页的鲜明对照。

十一、系列横向对比:工具型首页 vs 内容型首页

App 45 首页是工具型首页,与系列的内容型首页对比可看清两类首页的设计差异:

维度App 45 签到墙App 40 相册App 42 树洞
首页焦点签到状态卡渐变 Banner话题横滑
核心动作签到/去签到浏览/制作浏览/倾诉
数据展示连续天数/今日进度活动规模话题热度
内容组织活动清单瀑布流话题 + 树洞流
产品类型工具(效率)内容(浏览)内容(氛围)

工具型首页的三条原则:

  1. 动作置顶:签到墙首页第一屏就是"连续签到 + 去签到"(核心动作),内容型首页第一屏是"Banner + 内容流"(吸引浏览)——工具型产品"开门见山给动作",内容型"先营造氛围再引导"。
  2. 效率优先:工具型首页的信息密度高(签到卡 + 4 活动清单一屏密集排布),内容型首页重呼吸感(Banner + 卡片间距大)——工具的每寸屏幕服务效率、内容的每寸屏幕服务氛围。
  3. 状态可见:工具型首页展示"当前状态"(已签 2/3、连续 7 天、哪些活动待签),内容型首页展示"最新内容"——工具型首页是"仪表盘"、内容型首页是"橱窗"。

系列中的对照价值:App 45 与 App 40-44 恰好构成"工具 vs 内容"的两极——若把签到墙的"活动清单"加上内容流(签到动态广场),把内容型首页加上"待办动作卡",就能互相演化出混合型首页。理解两极才能设计中间态。

十二、开发者视角:首页的调试与验证技巧

  1. 双态按钮的分支测试:分别点击"已签到"(今日已签到)与"签到"(签到成功)两条路径——确认分支判断读取同一isMine状态源;再测试"isMine 翻转后按钮样式与 Toast 是否正确切换"。
  2. 签到卡数字的自洽:"7 连续签到"与我的页统计"7"、签到页本周签到(周一到周四 ✅)的核对——修改任一页需同步(系列验收标准)。
  3. 渐变卡的白字可读性:#FDCB6E黄渐变上的白色文字(7/连续签到(天))对比度——黄色较浅,白字需opacity(0.9)层次;真机验证各机型白字清晰。
  4. 长活动名的省略:"⏰ 07:00-08:00 · 128 人已签"这类副信息若活动名超长会换行挤压——maxLines(1)省略或调整布局(当前 4 个活动名均短,无碍)。
  5. 列表状态刷新:若实现"签到 → isMine 翻转",@State activities需整体重赋值(this.activities = this.activities.slice())——系列 @State 数组的经典坑,防漏。
  6. "去签到"的跳转:白色胶囊当前纯展示,产品化后挂onClick跳转签到 Tab(📍)——与签到页"立即签到"按钮衔接,两页联动需回归测试。

十三、FAQ 与一句话总结

Q6:为什么首页用黄色主题?黄色是"温暖、激励、活力"的语义色——签到是每天的小确幸(打卡成功如阳光般温暖),黄色贴合激励氛围;同时系列首次黄色主题也给了签到墙独特的品牌记忆点(与粉/紫/绿/淡紫形成色板补充)。

Q7:"128 人已签"和"128 累计签到"是同一个数字吗?纯属巧合——晨读 128 人是"今日签到人数"、我的页 128 天是"个人累计天数",两者同值但不同语义;不过巧合让"128"在 App 内形成记忆锚点,产品化时无需刻意规避。

Q8:活动列表能按热度排序吗?可以——按checked(已签人数)降序(自习室 234 → 晨读 128 → 晨跑 86 → 社团 45),热门活动置顶;当前按固定顺序(晨读/晨跑/自习室/社团),产品化按热度动态排序。

Q9:签到按钮会真的翻转状态吗?Demo 只弹 Toast 不翻转isMine——产品化后点击"签到"翻转isMine(按钮变"已签到")+ 人数 +1 + 签到卡进度更新,三处状态联动;签到页的checkedIn翻转是状态翻转的完整示范,首页可复用同模式。

Q10:首页的"去签到"和签到 Tab 是什么关系?"去签到"是签到 Tab 的快捷入口(跳转锚点)——签到卡是"状态展示"、签到 Tab 是"动作落地",首页看状态、签到页做动作,两页分工明确。这些 FAQ 与前面的拆解共同构成本页的完整解析。

最后从验收视角确认:四张实机截图覆盖了首屏(签到卡+活动列表)、已签到按钮点击(今日已签到 Toast)、签到按钮点击(签到成功 Toast)、完整列表(四活动全览)四个状态,黄色渐变卡、双态按钮、签到进度均验证正常。"7 连续签到"与"今日已签 2/3"在页面内数据一致。整页 97 行代码完成"工具型首页 + 签到状态展示"的完整结构,验收通过,可作为签到类工具首页的参考范本。

补充一句:签到墙的黄色,是每天坚持打出来的太阳色——每打一次卡,就点亮一点。 而"今日已签 2/3"的进度感、连续天数的成就感、双态按钮的操作感,正是签到墙让用户"明天还想来"的三重引擎——工具型首页的魅力,在于把枯燥的打卡变成看得见的坚持。 这就是签到墙首页,一个让坚持看得见的开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询