鸿蒙原生应用 ArkUI 实战:班级通讯录首页渐变卡与三快捷入口
鸿蒙原生应用 ArkUI 实战:班级通讯录首页渐变卡与三快捷入口
App 46「班级通讯录」首页(HomeTab),主题色
#0984E3蓝色(blue),4 个 Tab 分别为首页(🏠)、通讯录(👥)、班级(📋)、我的(👤)。首页采用"Header + 班级卡 + 联系人列表"三区布局——白色双行 Header("班级通讯录"22 号加粗 + “联系同学,就在此刻 📇”) + 蓝色渐变班级卡(👥 45 名成员 + 班级"计科2022级" + 公告/相册/群聊 3 个快捷入口按钮) + SectionTitle(老师与班委 + 全部 >)+ 3 位联系人(👩🏫 张老师·班主任 / 👨💻 王班长·班长 / 🧑🔧 陈生委·生活委员,每条含 44×44 蓝底圆头像 + 姓名 + 职务 + 绿色在线状态点 + 📞 呼叫按钮)。本篇基于46-class-contacts/entry/src/main/ets/pages/HomeTab.ets(共 100 行)逐段拆解,附 4 张实机截图。
一、整体结构:三区"Header + 班级卡 + 联系人列表"布局
首页是"品牌头部 + 班级总览 + 核心联系人"的三区布局——3 个 @Builder 块:
build() {
Column() {
this.Header()
Scroll() {
Column({ space: 14 }) {
this.ClassCard()
this.SectionTitle('老师与班委')
this.MemberList()
}
.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 块结构:
- Header — 双行品牌头(标题 + 副标题),白底固定
- ClassCard — 蓝色渐变班级总览卡,展示班级规模与快捷入口
- MemberList — “老师与班委” + 3 位核心联系人(老师 + 班长 + 班委)
首页定位是"班级总览"——先给用户班级的全局信息(45 人、班级名、快捷入口),再列出最常联系的老师与班委(带在线状态与呼叫按钮),是通讯录类产品"总览 + 高频联系人"的标准首页。

二、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: 4 })
Text('联系同学,就在此刻 📇').fontSize(12).fontColor(C.textDim).width('100%')
.padding({ left: D.pad, right: D.pad, bottom: 12 })
}.width('100%').backgroundColor(C.card)
}
细节:
- 标题:"班级通讯录"22 号加粗,直白点题(班级成员的通讯录)。
- 副标题:“联系同学,就在此刻 📇”——"就在此刻"强调"想联系随时可联系"的即时性,📇 名片 emoji 呼应通讯录形态。
- 安全区:
safeTop + 10避让状态栏,双行间距层次清晰。 - 白底全宽:系列双行 Header 范式。
三、ClassCard:班级渐变总览卡
ClassCard() {
Column({ space: 12 }) {
Row({ space: 12 }) {
Row() { Text('👥').fontSize(30) }
.width(52).height(52).backgroundColor('#33FFFFFF').borderRadius(26).justifyContent(FlexAlign.Center)
Column({ space: 4 }) {
Text('计科2022级').fontSize(17).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('45 名成员 · 班级通讯录').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
}
Row({ space: 10 }) {
ForEach(this.quickActs, (q: QuickAct) => {
Column({ space: 4 }) {
Text(q.emoji).fontSize(22)
Text(q.name).fontSize(11).fontColor('#FFFFFF')
}
.layoutWeight(1).padding({ top: 10, bottom: 10 }).backgroundColor('#22FFFFFF').borderRadius(D.rSm)
.onClick(() => { promptAction.showToast({ message: q.name }); })
}, (q: QuickAct) => q.name)
}.width('100%')
}
.width('100%').padding(16).borderRadius(D.rLg)
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
技术拆解:
- 蓝色渐变:
linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })从#0984E3蓝渐变到#4DA3F0浅蓝——系列首次蓝色主题,通讯录的"信任/专业"色调。 - 头行(半透明头像 + 班级信息):52×52 半透明白底 + 👥 图标 + "计科2022级"17 号加粗 + "45 名成员 · 班级通讯录"12 号 90% 透明度——班级名与规模。
- 3 个快捷入口:
ForEach渲染公告/相册/群聊三个按钮——每个layoutWeight(1)三等分、#22FFFFFF(约 13% 透明度)半透明底 + emoji + 名称——半透明块在渐变上呈"玻璃"质感(系列惯例),三个入口是班级功能的快捷通道:- 📢 公告(对应班级页公告)
- 📸 相册(对应纪念册式的班级相册)
- 💬 群聊(对应聊天入口)
- 点击反馈:点击弹入口名 Toast——产品化后分别跳转公告/相册/群聊页。
- 布局弹性:
layoutWeight(1)让三个入口等分,任何屏宽排版稳定。
四、MemberList:老师与班委列表
MemberList() {
Column({ space: 12 }) {
ForEach(this.members, (m: Member) => {
Row({ space: 12 }) {
Row() { Text(m.emoji).fontSize(22) }
.width(44).height(44).backgroundColor(C.primarySoft).borderRadius(22).justifyContent(FlexAlign.Center)
Column({ space: 3 }) {
Row({ space: 6 }) {
Text(m.name).fontSize(15).fontWeight(FontWeight.Medium).fontColor(C.text)
Text(m.role).fontSize(11).fontColor(C.textDim)
}.alignItems(VerticalAlign.Center)
Row({ space: 5 }) {
Circle().width(7).height(7).fill(m.online ? C.ok : C.textDim)
Text(m.online ? '在线' : '离线').fontSize(11).fontColor(m.online ? C.ok : C.textDim)
}
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text('📞').fontSize(18)
.padding(10).backgroundColor(C.primarySoft).borderRadius(18)
.onClick(() => { promptAction.showToast({ message: '呼叫 ' + m.name }); })
}
.width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
.onClick(() => { promptAction.showToast({ message: m.name }); })
}, (m: Member) => m.id.toString())
}.width('100%')
}
3 位核心联系人(20-25 行):
| 成员 | 职务 | 在线状态 |
|---|---|---|
| 👩🏫 张老师 | 班主任 | 在线 |
| 👨💻 王班长 | 班长 | 在线 |
| 🧑🔧 陈生委 | 生活委员 | 离线 |
卡片细节:
- 头像:44×44 蓝底圆 + 22 号 emoji(👩🏫 老师 / 👨💻 班长 / 🧑🔧 班委)——emoji 即职务形象的视觉符号。
- 姓名 + 职务:15 号 Medium 姓名 + 11 号浅灰职务(班主任/班长/生活委员)同一行,
alignItems(VerticalAlign.Center)垂直居中。 - 在线状态点:系列首次的在线状态组件——
Circle()7×7 圆形 +fill(m.online ? C.ok : C.textDim)(在线绿色 / 离线灰色)+ "在线/离线"文字(颜色同步)——小圆点即状态灯,通讯录产品的标配(类似微信的在线状态),绿点亮起即"可联系"的心理暗示。 - 📞 呼叫按钮:18 号 📞 + 10 padding + 蓝底圆角 18(
primarySoft)——独立挂载 onClick(“呼叫 XX”),与整卡点击(姓名 Toast)双事件层级:点 📞 呼叫、点卡其余区域看详情——系列中首次"卡内按钮与整卡双事件"的设计。 - 在线 vs 离线对比:张老师/王班长在线(绿点)、陈生委离线(灰点)——首屏即展示两种状态,用户理解"绿点 = 可联系"。
五、跨页数据自洽:首页是通讯录的"总览层"
首页与通讯录、班级、我的页的联动:
- “45 名成员” ↔ 班级页"总人数 45"、我的页副标题——45 是全班成员数,首页展示规模、班级页展示统计、我的页展示身份。
- 张老师/王班长/陈生委 ↔ 通讯录页相同成员(张娜/陈晨/王杰等是学生,张老师/王班长/陈生委是老师与班委)——首页展示"核心角色"、通讯录展示"全部成员"。
- 公告快捷入口 ↔ 班级页公告(置顶公告"春季运动会报名"等)——首页入口即班级页内容的快捷通道。
- 我的页"45 班级成员"统计 ↔ 首页"45 名成员"——同一数字两处一致。
六、实机截图与交互演示
本节结合 4 张实机截图,逐张还原首页的视觉效果与交互过程。
1. 首页首屏:班级卡 + 老师班委列表
第一张截图是进入 App 46 后的默认首屏:顶部"班级通讯录"标题与"联系同学,就在此刻 📇"副标题;下方蓝色渐变班级卡——👥 半透明头像 + “计科2022级” + “45 名成员 · 班级通讯录” + 三个半透明快捷入口(📢 公告 / 📸 相册 / 💬 群聊);再往下是"老师与班委"与第一位联系人——👩🏫 张老师(班主任 / 绿色在线点 / 📞)。蓝色主题专业清新,班级卡的总览感强。
2. 点击快捷入口:公告 Toast
第二张截图是点击班级卡"📢 公告"快捷入口后的反馈:弹出"公告"Toast。三个快捷入口独立挂载 onClick、闭包捕获 q.name,点击哪个入口就弹出哪个——产品化后跳转公告/相册/群聊对应页面,班级卡的快捷通道语义清晰。
3. 点击"📞":呼叫 Toast
第三张截图是点击"张老师"卡片右侧"📞"呼叫按钮后的反馈:弹出"呼叫 张老师"Toast——📞 按钮独立挂载 onClick 且闭包捕获 m.name,与整卡点击(弹姓名)形成双事件层级。产品化后此处调起系统拨号(@ohos.telephony 拨打张老师电话),📞 即通话入口。
4. 首页完整列表:三联系人全览
第四张截图是首页的完整列表视图:三位联系人全部可见——👩🏫 张老师(在线)、👨💻 王班长(在线)、🧑🔧 陈生委(离线,灰色状态点),在线/离线两种状态同屏对比。Scroll 滚动流畅,底部安全区内边距保证 Tab 栏可点。
七、扩展思考:在线状态与实时通信的关联
在线状态点是通讯录产品的关键组件,其背后是实时通信的能力:
- 状态的真实性:Demo 的在线/离线是静态标记——真实产品通过长连接(WebSocket)或推送心跳上报在线状态,
Circle().fill(...)的颜色随状态实时刷新。 - 状态的粒度:在线/离线之上可细分"忙碌/勿扰/离线"多态(颜色区分:绿/黄/灰)——状态粒度影响呼叫决策(勿扰时不宜打扰)。
- 状态与呼叫的联动:在线时 📞 可点击(可拨打)、离线时置灰(提示"对方离线")——状态驱动操作可用性,避免"打了没人接"的无效呼叫。
- 最后在线时间:离线可显示"最后在线 2 小时前"——比单纯灰点更有信息量(
lastSeen字段)。 - 隐私与状态:用户可关闭状态可见性(“隐身”)——状态是个人隐私(我的页隐私设置),产品需尊重用户的状态可见权。
八、扩展思考:通讯录的双事件层级设计
首页"📞 独立按钮 + 整卡点击"的双事件层级是通讯录的标准交互,其设计原则:
- 主次动作分离:整卡点击 = 次要动作(查看详情)、📞 按钮 = 主要动作(呼叫)——高频动作独立成大按钮、低频动作整卡承载,用户手指落在 📞 上直接呼叫、落在卡上查看详情,互不干扰。
- 热区设计:📞 按钮 18 号 emoji + 10 padding + 圆角 18(约 38×38 热区)——接近 44dp 触控规范;若热区过小(< 32)误触率升高,本页的 padding 恰到好处。
- 事件冒泡:📞 的 onClick 与整卡的 onClick 是兄弟事件(📞 内层、整卡外层)——点击 📞 时只触发呼叫(📞 的 onClick 拦截,不冒泡到整卡),ArkUI 的组件级事件天然隔离,无需 stopPropagation。
- 与系列其他"双动作"卡片的对比:App 38 技能卡"交换按钮 + 整卡"、App 45 签到卡"签到按钮 + 整卡"同模式——"主按钮 + 整卡"是功能列表卡片的通用层级,本页的 📞 是最典型的示范。

九、开发者视角:首页的调试与验证技巧
- 在线状态的测试:分别验证在线(绿点 + "在线"绿字)与离线(灰点 + "离线"灰字)两种渲染——
Circle().fill(m.online ? C.ok : C.textDim)的三元分支正确性是验收点。 - 双事件层级:点击 📞 区域(应弹"呼叫 XX")与点击卡片其余区域(应弹姓名)——确认两事件互不干扰(无"点了 📞 弹了两个 Toast"的冒泡问题)。
- 半透明快捷入口的对比:
#22FFFFFF(约 13% 透明度)块在蓝色渐变上的可读性——真机验证 11 号白字在 13% 白底上清晰(对比度不足则加深底透明度)。 - 长职务名:职务(生活委员)4 字 + 姓名同行——若职务超长(“学生会文体部部长”)会挤压姓名,
Row内文本需省略或换行策略。 - 数据自洽:45 名成员与班级页"总人数 45"、我的页统计一致——修改需同步(系列验收标准)。
十、FAQ 与一句话总结
Q1:为什么首页先展示"老师与班委"而不是全部成员?
高频优先——老师(张老师)与班委(班长/生活委员)是班级中最常被联系的人,首页"总览 + 高频"的结构让用户不用翻列表就能找到最重要的人;全部成员在通讯录 Tab 按字母排序展示。
Q2:在线状态是怎么实现的?
Demo 用静态 online 字段渲染(绿/灰点)。真实产品通过长连接/推送上报在线状态,Circle().fill() 颜色随状态刷新——状态组件本身已是真实实现,数据源产品化即可。
Q3:"📞"点击后真的会打电话吗?
Demo 弹 Toast。产品化后调起系统拨号(@ohos.telephony.call 或 startAbility 拨号盘),传入联系人号码——📞 是通话入口,Toast 是其原型占位。
Q4:公告/相册/群聊三个入口是做什么的?
班级功能的快捷通道——公告对应班级页公告列表、相册对应班级照片(App 44 纪念册模式)、群聊对应班级群消息;产品化后分别跳转对应页面。
Q5:为什么班级卡用蓝色渐变?
蓝色是"信任、专业、联系"的语义色——通讯录是"可靠的联系工具"(随时能联系到人),蓝色传递专业与可靠;同时系列首次蓝色主题与粉/紫/绿/黄/淡紫形成色板补充,品牌记忆点独特。
一句话总结:首页以"班级总览卡 + 老师班委列表"完成了通讯录的总览层。"45 名成员"的规模背书、公告/相册/群聊三个快捷入口、在线状态点(绿/灰)与 📞 呼叫按钮的双事件层级——100 行代码,一个让"联系同学就在此刻"的班级通讯录首页,也是"总览 + 高频联系人"通讯录首页的标准范式。

十一、系列横向对比:通讯录类首页 vs 社交类首页
App 46 首页是"通讯录类首页",与系列社交类首页对比可看清两类产品的差异:
| 维度 | App 46 通讯录 | App 39 兴趣匹配 | App 38 技能交换 |
|---|---|---|---|
| 首页焦点 | 班级总览卡 | 今日匹配卡 | 分类胶囊 |
| 核心对象 | 班级成员(实名) | 兴趣用户 | 技能达人 |
| 核心动作 | 呼叫/查看 | 打招呼 | 交换 |
| 数据维度 | 成员数/在线状态 | 匹配度/标签 | 技能/等级 |
| 关系基础 | 同学(现实关系) | 兴趣(虚拟匹配) | 技能(价值交换) |
通讯录的差异:
- 关系是"既有的":通讯录的关系是"班级同学"(现实既定关系),首页不需要"发现/匹配"(App 39 的匹配机制)——通讯录首页直接服务既有关系(呼叫/联系),社交首页负责建立新关系。
- 状态实时性:通讯录的在线状态点(绿/灰)是"此刻可联系"的实时信号——社交 App 的"在线"通常淡化(不强调即时打扰),通讯录强调"现在能不能找到人",通讯录的时间敏感度远高于社交。
- 实名信任:通讯录全员实名(张老师/张娜),社交多用昵称/匿名——通讯录的信任来自现实关系,社交的信任来自平台机制,首页的"45 名成员"实名背书让联系零门槛。
复用价值:首页"班级总览卡 + 快捷入口 + 在线状态列表"的模板可直接复用到任何"组织通讯录"(社团、部门、课题组),把"成员规模"换成"组织规模"、“呼叫"换成"联系”,即可快速生成组织通讯录产品。

十二、开发者视角:首页的调试与验证技巧
- 在线状态的测试:分别验证在线(绿点 + "在线"绿字)与离线(灰点 + "离线"灰字)两种渲染——
Circle().fill(m.online ? C.ok : C.textDim)的三元分支正确性是验收点。 - 双事件层级:点击 📞 区域(应弹"呼叫 XX")与点击卡片其余区域(应弹姓名)——确认两事件互不干扰(无"点了 📞 弹了两个 Toast"的冒泡问题)。
- 半透明快捷入口的对比:
#22FFFFFF(约 13% 透明度)块在蓝色渐变上的可读性——真机验证 11 号白字在 13% 白底上清晰(对比度不足则加深底透明度)。 - 长职务名:职务(生活委员)4 字与姓名同行——若职务超长(“学生会文体部部长”)会挤压姓名,
Row内文本需省略或换行策略。 - 数据自洽:45 名成员与班级页"总人数 45"、我的页统计一致——修改需同步(系列验收标准)。
- 状态点尺寸:
Circle()7×7 在 44 高卡片内的垂直居中——与文字基线对齐需Row的alignItems(VerticalAlign.Center)配合,真机确认状态点与文字不偏位。
十三、FAQ 与一句话总结
Q6:为什么首页没有搜索框?
首页是"总览"(班级卡 + 高频联系人),搜索是"全集"的检索工具——搜索框放在通讯录页(全集列表)更合适;首页 3 位核心联系人无需搜索,45 人全集才需要。搜索的位置跟随列表规模。
Q7:在线状态是实时刷新的吗?
Demo 静态。真实产品通过长连接/推送更新,Circle().fill() 颜色随状态刷新——状态组件已就绪,数据源产品化(WebSocket 心跳)即可实时。
Q8:快捷入口的三个功能(公告/相册/群聊)在真实产品中在哪?
公告在班级页、相册可独立(纪念册模式)、群聊独立页——首页入口是"跨页快捷通道"(一屏直达高频功能),与各功能的完整页并存,入口跳转产品化。
Q9:呼叫需要什么权限?
拨号需 @ohos.permission.CALL_PHONE 权限(首次呼叫申请)+ 对方号码可见——权限说明文案(“用于拨打班级同学电话”)在申请时展示,符合最小权限原则。
Q10:首页为什么先列老师与班委?
高频优先——张老师(班主任)、王班长、陈生委是班级事务中最常被联系的角色;普通同学在通讯录页按学号/字母检索——"总览置顶高频、全集承接低频"的两级结构。这些 FAQ 与前面的拆解共同构成本页的完整解析。
最后从验收视角确认:四张实机截图覆盖了首屏(班级卡+老师班委列表)、快捷入口点击(公告 Toast)、📞 呼叫(呼叫张老师 Toast)、完整列表(三联系人全览)四个状态,蓝色渐变班级卡、半透明快捷入口、在线状态点(绿/灰)、双事件层级均验证正常。跨页数据自洽通过核对——“45 名成员"与班级页"总人数 45”、我的页"45 班级成员"完全一致,“计科2022级"三页统一,张老师/王班长/陈生委与通讯录页成员体系一致。整页 100 行代码完成"班级总览 + 高频联系人"的通讯录首页,验收通过,可作为通讯录类产品首页的参考范本。若进一步扩展,可参考本系列方法将班级卡升级为"班级数据看板”(性别环形图、籍贯分布),让首页从"总览卡"演进为"班级画像",其交互与布局骨架无需改动,只需在班级卡内增加统计可视化区块——这一升级路径与系列"先静态后数据"的方法论一脉相承,也是本页未来演进的清晰方向。
补充一处细节观察:首页的在线状态点(Circle() 7×7)与呼叫按钮(📞)形成了"状态 → 动作"的视觉链路——绿点亮起(在线)时用户自然想到"可以打📞",灰点(离线)时则犹豫"要不要打扰";这种"状态先行、动作随后"的编排,让用户不读任何文字就能完成"判断可联系性 → 决定呼叫"的决策,是通讯录首页最无声却最有效的交互引导。而三个快捷入口(公告/相册/群聊)的半透明玻璃块(#22FFFFFF),则在蓝色渐变上形成"入口感"与"功能感"的双重暗示——半透明既是系列一贯的质感手法,也暗示"这些是快捷通道,点进去还有完整页面",与首页"总览"的定位完全吻合。这些细节虽不显眼,却共同决定了通讯录首页"可靠、清晰、高效"的整体观感。

更多推荐





所有评论(0)