鸿蒙 Next 搭子雷达 App 开发实战:兴趣匹配 + 活动标签 + 在线状态



鸿蒙 Next 搭子雷达 App 开发实战:兴趣匹配 + 活动标签 + 在线状态
作者:duluo
SDK 版本:HarmonyOS API 24 (Next)
开发工具:DevEco Studio
语言框架:ArkTS + ArkUI
字数:约 9600 字
目录
1. 引言
1.1 搭子文化的兴起
“搭子”——这是一个在年轻人中流行的词,指的是"一起做某件事的临时伙伴"。饭搭子(一起吃饭)、球搭子(一起运动)、学习搭子(一起自习)、旅游搭子(一起旅行)。
搭子与传统朋友的区别在于:搭子是功能性的,朋友是情感性的。 你不需要和搭子有深厚的感情基础,只需要有一个共同的活动目标。吃完饭可以各回各家,打完球可以不再联系——没有社交压力。
"搭子雷达"App 解决的问题很简单:当你突然想吃饭/运动/学习却找不到人时,快速发现附近也在找搭子的人。
1.2 本 App 的社交定位
本 App 是系列中第五款社交/平台类 App:
| App | 连接方式 | 目标 |
|---|---|---|
| 23 情绪漂流瓶 | 匿名倾诉 | 情绪释放 |
| 29 反向导师 | 技能教学 | 知识传递 |
| 35 二手流转 | 物品交易 | 物品循环 |
| 36 共享工具库 | 工具共享 | 邻里互助 |
| 38 搭子雷达 | 兴趣匹配 | 临时社交 |
1.3 三十八款 App 全景
App 数量: 38
代码总行数: ~20,000 行
编译错误数: ~315 个
博客总字数: ~380,000 字
技术博客数: 38 篇
2. 产品概念与搭子模型
2.1 功能需求
用户故事 1:我想找个人今晚一起吃饭
用户故事 2:我想按活动类型筛选搭子
用户故事 3:我想知道对方是否在线
用户故事 4:我想联系搭子表达组队意向
功能清单:
├── F1: 搭子列表(10 位搭子)
├── F2: 7 个活动标签筛选
├── F3: 搭子卡片(头像/年龄/活动/时间/距离/状态)
├── F4: 在线/忙碌状态标识
├── F5: 详情弹窗
├── F6: 组队操作
├── F7: 已组队列表
└── F8: 在线人数统计
2.2 搭子数据模型
interface Partner {
id: number;
name: string; // 昵称
emoji: string; // 头像
age: number; // 年龄
activity: string; // 找搭子描述
time: string; // 时间
dist: string; // 距离
desc: string; // 详细介绍
tag: string; // 活动分类
status: string; // 在线状态
}
10 个字段,比标准平台类模型多了 activity、time、status 三个字段。activity 和 time 是搭子的核心信息——“找什么搭子"和"什么时候”。
2.3 10 位搭子的覆盖
| 活动类型 | 搭子数 | 时间分布 |
|---|---|---|
| 吃饭 | 1 | 今晚 |
| 运动 | 3 | 明天/每天/周末 |
| 学习 | 1 | 今晚 |
| 娱乐 | 2 | 周五/晚上 |
| 社交 | 2 | 今天/每天 |
| 户外 | 1 | 下周末 |
运动类最多(3 位),反映了"运动需要搭子"的真实需求——一个人跑步、打球、骑行确实不如有伴容易坚持。
3. 两 Tab 架构设计
3.1 Tab 配置
build() {
Stack() {
Column().backgroundColor(C.bg)
Column() {
this.buildHeader()
if (this.activeTab === 0) this.buildRadarTab()
else this.buildMyTab()
this.buildTabBar()
}
if (this.showDetail) this.buildDetailOverlay()
}
}
| Tab | 图标 | 功能 |
|---|---|---|
| 0 | 📡 | 雷达 — 浏览搭子列表 |
| 1 | 🤝 | 搭子 — 已组队列表 |
3.2 顶部栏在线统计
Text('附近 ' + this.getOnlineCount() + ' 人在线')
getOnlineCount() 遍历所有搭子,统计 status 为 ‘在线’ 的人数。这个数字在运行时不会变化(因为数据是静态的),但它传达了一个信息——“这个 App 有人用”。
4. 首页雷达与标签筛选
4.1 7 个活动标签
const TAGS: string[] = ['全部', '吃饭', '运动', '学习', '娱乐', '社交', '户外'];
7 个标签覆盖了最常见的搭子类型。标签数量比"共享工具库"(4 个)和"二手流转"(5 个)都多,反映了搭子活动的多样性。
4.2 筛选逻辑
与之前的 App 完全相同——selectedTag 控制筛选,getFiltered() 返回当前分类的数据。这个方法在 ForEach 和详情弹窗两处被调用。
5. 搭子卡片组件
5.1 卡片布局
┌──────────────────────────────────┐
│ 👩 小陈 · 28岁 🟢 在线 │
│ 找饭搭子 │
│ ⏰ 今晚6点 📍 500m │
│ │
│ 想去新开的日料店尝尝… │
│ │
│ 吃饭 💬 组队 │
└──────────────────────────────────┘
五行信息:头像 + 年龄 + 状态(第一行)→ 活动说明(第二行)→ 时间 + 距离(第三行)→ 描述(第四行)→ 分类标签 + 组队按钮(第五行)。
5.2 状态指示器
Text('🟢').fontSize(12)
.fontColor(p.status === '在线' ? C.accent : C.textMuted)
Text(p.status).fontSize(10).fontColor(C.textMuted)
绿色圆点 + "在线"文字;灰色圆点 + "忙碌中"文字。使用 emoji 圆点(🟢)替代自定义图标,减少了代码量。
5.3 忙碌状态的处理
if (p.status === '在线') {
// 显示组队按钮
Text(this.isConnected(p.id) ? '✅ 已联系' : '💬 组队')
} else {
Text('⏳ 忙碌中').fontSize(13).fontColor(C.textMuted)
}
忙碌状态的搭子不显示组队按钮,只显示灰色"⏳ 忙碌中"文字。
6. 在线状态系统
6.1 状态数据
10 位搭子中,8 位"在线",2 位"忙碌"(小李和小马)。
在线比例 80%,传递了"这个 App 很活跃"的信号。如果所有搭子都在线,显得不真实;如果大部分都不在线,用户会失去兴趣。80% 的在线率是一个经过设计的平衡点。
6.2 在线统计
getOnlineCount(): number {
let c = 0;
for (const p of PARTNERS) { if (p.status === '在线') c++; }
return c;
}
在顶部栏实时显示在线人数。虽然数据是静态的,但展示这个数字本身就能传达"有人在用"的感觉——对社交类 App 来说,这是最重要的信息。
7. 详情弹窗与组队流程
7.1 详情弹窗
┌──────────────────────────────┐
│ 👩 │
│ 小陈 · 28岁 │
│ 28岁 · 找饭搭子 │
│ ───────────────────────── │
│ ⏰ 今晚6点 📍 500m │
│ │
│ 📝 详情 │
│ 想去新开的日料店尝尝… │
│ │
│ 💬 组队 │
└──────────────────────────────┘
弹窗展示完整信息:头像(64sp)→ 姓名年龄 → 活动说明 → 分割线 → 时间距离 → 详细介绍 → 组队按钮。
7.2 组队流程
connectPartner(id: number): void {
this.connected = [id, ...this.connected];
promptAction.showToast({ message: '🤝 组队成功!快去打个招呼吧' });
}
3 行代码完成组队操作。Toast 提示"快去打个招呼吧"——这是在引导用户的下一步行动。
8. 社交类 App 设计模式
8.1 五款社交类 App 的共性
从 App 23 到 App 38,五款社交类 App 共享以下模式:
模式一:两数组状态
@State interested: number[] = []; // 或 requests / connected / borrowed
用一维数组存储"已操作"的 ID,用 indexOf() 查询状态。
模式二:卡片 + 详情弹窗
所有社交类 App 都采用"卡片列表 + 点击弹窗查看详情"的模式。卡片展示概要信息,弹窗展示完整信息。
模式三:两 Tab 布局
浏览 Tab + 我的 Tab。浏览 Tab 负责发现,我的 Tab 负责管理。
8.2 五款社交类 App 的差异
| App | 操作动词 | 状态数组 | 特殊元素 |
|---|---|---|---|
| 23 漂流瓶 | 捞取/回信 | isReplied | 随机匹配 |
| 29 导师 | 申请 | requests | 导师角色 |
| 35 二手 | 联系 | interested | 价格标签 |
| 36 工具 | 借出/归还 | borrowed | 归还功能 |
| 38 搭子 | 组队 | connected | 在线状态 |
8.3 社交类 App 的最小可行模型
经过 5 款社交类 App 的实践,总结出社交类 App 的最小可行模型:
1 个数组(已操作 ID 列表)
2 个 Tab(浏览 + 我的)
3 个核心方法(isXxx、doXxx、getFiltered)
用这个模型,可以在 250-300 行代码内实现一款完整的社交类 App。
9. 编译错误全记录
9.1 错误概览
本 App 实现 0 个编译错误——系列第四次零错误。
前三次零错误:App 31(慢病管理)、App 33(相亲防骗)、App 37(旧衣盲盒)。
9.2 零错误率趋势
前 10 款: 0/10 = 0%
11-20 款: 0/10 = 0%
21-30 款: 0/10 = 0%
31-38 款: 4/8 = 50%
最近 8 款 App 中 4 款零错误,零错误率 50%。趋势明显——零错误已经成为"新常态"。
10. 第三十八款 App 全景回顾
10.1 数据总览
| 指标 | 数值 |
|---|---|
| 代码行数 | 274 行 |
| 编译错误数 | 0 个 |
| @State 变量 | 4 个 |
| @Builder 方法 | 6 个 |
| 搭子数量 | 10 位 |
| 活动标签 | 7 个 |
| Tab 数 | 2 个 |
| 弹窗数 | 1 个 |
| 外部依赖 | 0 个 |
10.2 社交类 App 代码量对比
App 23: 情绪漂流瓶 447 行
App 29: 反向导师 373 行
App 35: 二手流转 266 行
App 36: 共享工具库 295 行
App 38: 搭子雷达 274 行
社交类 App 的平均代码量约 331 行,呈下降趋势。
11. 结语
11.1 搭子的意义
搭子不是朋友,但比陌生人近一步。它是一种"低承诺、低成本"的社交方式——不需要维护长期关系,不需要考虑对方感受,只需要在共同活动中享受陪伴。
对于在大城市生活的年轻人来说,搭子是一种"刚刚好"的社交距离:不是一个人(孤独),也不是谈恋爱(沉重),只是一起吃顿饭、跑个步、看场电影。
11.2 第四次零错误
第四次零错误的意义:零错误已经成为常规,不再是新闻。
从第一次零错误的"激动"到第四次零错误的"平淡",这个过程本身就是技术成长的体现。当你的代码第一次零错误构建时,你会觉得是运气。当第四次发生时,你会觉得"本来就该这样"。
11.3 给开发者的建议
- 社交类 App 用两数组状态就够了——不需要复杂的状态管理库
- 在线状态是社交 App 的启动信号——显示"XX 人在线"比显示"XX 件物品"更能促使用户行动
- 38 款 App 证明了 ArkUI 的成熟度——从白噪音到搭子雷达,ArkUI 都做得来
11.4 致谢
38 款 App、38 篇博客。感谢每一位读到这里的读者。
现在,打开 DevEco Studio,去创造属于你自己的 App 吧。
附录 A:核心代码速查
在线统计
getOnlineCount(): number {
let c = 0;
for (const p of PARTNERS) { if (p.status === '在线') c++; }
return c;
}
组队操作
connectPartner(id: number): void {
this.connected = [id, ...this.connected];
promptAction.showToast({ message: '🤝 组队成功!' });
}
分类筛选
getFiltered(): Partner[] {
if (this.selectedTag === 0) return PARTNERS;
const result: Partner[] = [];
for (const p of PARTNERS) { if (p.tag === TAGS[this.selectedTag]) result.push(p); }
return result;
}
更多推荐



所有评论(0)