【OpenHarmony/HarmonyOS】项目实战:分享中心与近场学习报告设计
·
【OpenHarmony/HarmonyOS】项目实战:分享中心与近场学习报告设计
摘要
分享功能不只是把一段文字发出去。对于学习项目来说,分享可以承载成就感、打卡动力和社交传播。本文结合「英语视界 YingYu」项目,分享如何基于 ShareKit 设计学习报告、成就徽章、生词本等分享内容,并支持碰一碰和隔空传送。📤
相关文件:
entry/src/main/ets/utils/ShareService.ts
entry/src/main/ets/pages/ShareCenter.ets
entry/src/main/ets/pages/ShareGuide.ets
entry/src/main/ets/pages/ProfileContent.ets
一、为什么学习项目需要分享中心?
学习是长期行为,分享能提供外部反馈:
- 给家长展示学习成果;
- 和同学互相鼓励;
- 分享连续打卡;
- 分享自定义生词;
- 分享成就徽章;
- 形成学习仪式感。
「英语视界」的分享中心不是简单调用系统分享,而是先把学习数据整理成可读报告。
二、分享数据模型
学习报告数据:
export interface LearningRecordShareData {
totalWords: number
totalDays: number
consecutiveDays: number
achievementsCount: number
achievementsTotal: number
customWordsCount: number
reviewDueCount: number
todayProgress: string
shareDate: string
}
成就分享数据:
export interface AchievementShareData {
achievements: Achievement[]
achievementsCount: number
totalAchievements: number
shareDate: string
}
生词本分享数据:
export interface CustomWordsShareData {
words: CustomWord[]
totalCount: number
shareDate: string
}
通过不同数据模型,可以支持多种分享内容。
三、生成学习报告数据
项目通过 generateShareContent() 聚合学习数据:
export function generateShareContent(type: ShareContentType = 'learning_record') {
const today = new Date()
const shareDate = `${today.getFullYear()}年${today.getMonth() + 1}月${today.getDate()}日`
if (type === 'learning_record') {
const stats = getStatistics()
const extendedStats = getExtendedStatistics()
return {
totalWords: stats.totalWords,
totalDays: stats.totalDays,
consecutiveDays: stats.consecutiveDays,
achievementsCount: stats.achievementsCount,
achievementsTotal: 12,
customWordsCount: extendedStats.customWordsCount,
reviewDueCount: extendedStats.reviewDueCount,
todayProgress: `${stats.totalWords} 词 | ${stats.consecutiveDays} 天连续`,
shareDate: shareDate
}
}
}
这里复用了:
getStatistics();getExtendedStatistics();getAchievements();getCustomWords()。
四、分享文案设计
学习报告文本:
export function generateLearningRecordText(data: LearningRecordShareData): string {
return `🎓 我的英语学习报告\n\n📅 ${data.shareDate}\n\n` +
`✨ 已学单词: ${data.totalWords} 个\n` +
`📅 学习天数: ${data.totalDays} 天\n` +
`🔥 连续打卡: ${data.consecutiveDays} 天\n` +
`🏆 获得成就: ${data.achievementsCount}/${data.achievementsTotal}\n` +
`📚 自定义词: ${data.customWordsCount} 个\n` +
`🔄 待复习: ${data.reviewDueCount} 个\n\n` +
`💪 坚持学习,遇见更好的自己!\n` +
`📱 使用「趣味英语」App 一起学习吧~`
}
好的分享文案应该具备:
- 数据明确;
- 情绪积极;
- 易读;
- 有传播感;
- 不暴露隐私。
五、成就分享
成就分享文本:
export function generateAchievementsText(data: AchievementShareData): string {
const unlockedList = data.achievements.filter(a => a.unlocked)
let text = `🏆 我的成就徽章\n\n📅 ${data.shareDate}\n\n` +
`已解锁 ${data.achievementsCount}/${data.totalAchievements} 个成就\n\n`
if (unlockedList.length > 0) {
text += `✨ 已获得:\n`
for (const ach of unlockedList) {
text += `${ach.icon} ${ach.title}\n`
}
}
text += `\n💪 继续努力,解锁更多成就!`
return text
}
成就分享适合在用户解锁新徽章后触发。
六、生词本分享
生词本分享支持展示最近添加的词:
export function generateCustomWordsText(data: CustomWordsShareData): string {
let text = `📚 我的单词本\n\n📅 ${data.shareDate}\n\n` +
`共收录 ${data.totalCount} 个单词\n\n`
if (data.words.length > 0) {
const displayWords = data.words.slice(0, 10)
text += `✨ 最近添加:\n`
for (const word of displayWords) {
text += `• ${word.word}: ${word.translation}\n`
}
}
return text
}
这里限制最多展示 10 个词,是很好的隐私和可读性设计。
七、近场分享监听
碰一碰分享:
export function registerKnockShare(callback: (target: harmonyShare.SharableTarget) => void): void {
harmonyShare.on('knockShare', (target: harmonyShare.SharableTarget) => {
console.info('Triggered Knock Share')
callback(target)
})
}
隔空传送:
export function registerGesturesShare(callback: (target: harmonyShare.SharableTarget) => void): void {
harmonyShare.on('gesturesShare', (target: harmonyShare.SharableTarget) => {
console.info('Triggered Gestures Share')
callback(target)
})
}
主页面中注册:
registerShareListeners(): void {
if (this.isPhone) {
registerKnockShare((target: harmonyShare.SharableTarget) => {
handleShareFromKnock(target, 'learning_record')
})
registerGesturesShare((target: harmonyShare.SharableTarget) => {
handleShareFromKnock(target, 'learning_record')
})
}
}
八、发起分享
核心分享逻辑:
export async function handleShareFromKnock(
target: harmonyShare.SharableTarget,
type: ShareContentType = 'learning_record'
): Promise<boolean> {
const shareText = generateShareText(type)
const shareData: systemShare.SharedData = new systemShare.SharedData({
utd: utd.UniformDataType.TEXT,
content: shareText
})
target.share(shareData)
return true
}
这里使用文本类型,是因为学习报告最容易在不同 App 间流转。
九、个人中心入口
个人中心中有分享入口:
SymbolGlyph($r('sys.symbol.share'))
.fontSize(this.isTabletDevice ? 22 : 20)
.fontColor([$r('app.color.primary_color')])
.onClick(() => {
router.pushUrl({ url: 'pages/ShareCenter' })
})
并提示支持近场分享:
Text('支持隔空传送和碰一碰分享学习记录')
.fontSize(this.isTabletDevice ? 13 : 11)
.fontColor($r('app.color.primary_color'))
这能让用户知道分享能力的存在。
十、分享内容的隐私边界
学习报告不应该包含:
- 用户邮箱;
- 真实姓名;
- 学校;
- 具体错题;
- 完整学习日志;
- 未经确认的生词全文。
当前分享内容只包含统计数据和少量生词,非常适合公开传播。
十一、后续扩展方向
可以继续扩展:
- 生成学习海报;
- 分享成就卡片图片;
- 分享每日一句;
- 分享复习计划;
- 支持班级学习榜;
- 分享 AppLink 回到具体页面。
但每次扩展都要控制隐私边界。
十二、小结
本文结合「英语视界 YingYu」项目,拆解了分享中心和近场学习报告设计:
- 使用结构化数据生成学习报告;
- 支持学习记录、成就、生词本三类分享;
- 文案强调成就感和鼓励感;
- 通过 ShareKit 支持碰一碰和隔空传送;
- 分享内容控制在统计和摘要层面,避免隐私泄露;
- 个人中心提供可感知入口。
分享功能的关键不是“能发出去”,而是让用户愿意分享,并且分享得安全、体面、有成就感。✨

更多推荐



所有评论(0)