【OpenHarmony/HarmonyOs 】从化学学习 App 出发:近场快传、实况窗与全场景智慧学习方案
本文基于「化学视界」这个 HarmonyOS 项目展开。当前项目已经具备离线题库、元素周期表、方程式、收藏、错题、成就、学习统计、平板适配等能力。本文重点不是说这些能力已经全部接入系统级近场快传和实况窗,而是说明:在现有项目结构上,如何自然扩展到近场分享、实况窗提醒和全场景智慧学习。🚀
一、项目为什么适合做“全场景学习”?
化学学习有一个明显特点:学习发生在多个碎片场景里。
- 上课时快速查一个元素。
- 做题时查看方程式现象。
- 晚上复习错题。
- 通勤时刷每日一题。
- 平板上横屏看周期表。
- 和同学分享某个元素、方程式或知识点。
这些场景天然适合鸿蒙生态的全场景能力:手机负责随手查,平板负责大屏学习,分享能力负责资料流转,实况窗负责把“正在进行的挑战”留在系统可见位置。
当前项目已经有一些基础:
- 📱
deviceTypes支持phone和tablet。 - 🧩 页面路由清晰,详情页可通过参数打开。
- ⭐ 收藏、错题、成就数据本地保存。
- ⏱️ 限时挑战有明确的倒计时状态。
- 📤 元素详情页已经预留分享按钮。
- ☁️ 配置了备份扩展能力。
模块配置如下:
{"deviceTypes": ["phone","tablet"],"extensionAbilities": [ {"name":"EntryBackupAbility","type":"backup","exported": false } ] }这为后续的“全场景智慧生活”扩展打好了底。
二、近场快传:学习内容最小单元化
近场快传的核心不是“传整个 App”,而是传一个清晰、轻量、可被接收方理解的学习对象。
在化学学习 App 里,适合作为分享单元的内容有:
- 一个元素:例如 H、Na、Fe。
- 一个方程式:例如铁与氧气反应。
- 一个知识点:例如质量守恒定律。
- 一组错题:例如今天答错的 5 道题。
- 一次挑战结果:例如 10 题正确 8 题。
项目的元素详情页已经有分享按钮:
Row(){ Image($r('app.media.icon_share')).width(20).height(20).fillColor($r('app.color.text_tab_inactive')) }.width(40).height(40).borderRadius(20).backgroundColor($r('app.color.background_color')).scale({ x: this.shareButtonScale, y: this.shareButtonScale})目前这只是一个 UI 入口,后续可以把它接成系统分享、近场快传或自定义 Want 跳转。建议先定义统一的分享数据结构:
interface SharePayload { type:'element'|'equation'|'knowledge'|'quizResult'; id: string; title: string;summary: string; deepLink: string; }比如元素详情页可以生成:
constpayload:SharePayload= {type:'element',id:String(this.elementLocal.number),title:`${this.elementLocal.name}(${this.elementLocal.symbol})`,summary:`原子序数${this.elementLocal.number},原子量${this.elementLocal.atomicMass}`,deepLink:`huaxue://element/${this.elementLocal.number}`};这样不管是系统分享、近场快传,还是未来接入碰一碰、跨设备流转,都可以复用同一份数据。
三、详情页路由:让分享内容可以被精准打开
当前项目详情页通过router.getParams()接收参数,例如元素详情:
letparams= router.getParams()asRecord<string, number>;if(params&¶ms.elementNumber) {letel = getElementByNumber(params.elementNumber);if(el) {this.element = el;this.elementLocal = el;this.isFavorite = isFavorited('element', String(el.number)); } }这意味着只要分享内容里带上elementNumber,接收方就能直接打开对应元素详情页,而不是从首页重新搜索。
推荐的扩展方式:
- 分享时生成
type + id。 - 接收方解析
type。 - 根据类型跳转到对应页面。
- 页面使用原有参数加载内容。
伪代码如下:
functionopenSharedPayload(payload:SharePayload) {if(payload.type=== 'element') {router.pushUrl({url: 'pages/periodic/ElementDetail',params: {elementNumber:Number(payload.id) }}); }if(payload.type=== 'equation') {router.pushUrl({url: 'pages/equations/EquationDetail',params: {equationId:Number(payload.id) }}); } }这一步是近场快传体验的关键:传输只是入口,真正影响体验的是“对方打开后是否一步到位”。
四、实况窗:最适合接入限时挑战
在这个项目里,最适合接入实况窗的模块是“限时挑战”。因为它具备典型的实时状态:
- 当前正在答第几题。
- 剩余时间。
- 正确数和错误数。
- 挑战是否结束。
TimeChallengeView中已经有这些状态:
@StateprivatechallengeState: string ='setup';@StateprivatequestionCount: number =10;@StateprivatetimePerQuestion: number =60;@StateprivatecurrentIndex: number =0;@StateprivateremainingSeconds: number =0;@StateprivatecorrectCount: number =0;@StateprivatewrongCount: number =0;这几项可以抽象成实况窗展示模型:
interfaceChallengeLiveState{ title:string; progressText:string; remainingText:string; scoreText:string; }生成状态时可以这样写:
constliveState:ChallengeLiveState= {title:'化学限时挑战',progressText:`${this.currentIndex +1}/${this.questionCount}`,remainingText:this.remainingSeconds>0?`${this.remainingSeconds}s`:'不限时',scoreText:`对${this.correctCount}· 错${this.wrongCount}`};接入实况窗后,用户即使暂时切到其他应用,也能看到挑战还剩多久。对学习 App 来说,这种提醒不是打扰,而是帮助用户维持学习节奏。⏱️
五、全场景智慧生活:手机、平板、备份恢复
当前项目已经支持手机和平板:
"deviceTypes": ["phone","tablet"]页面里也做了平板断点判断:
constdisplayClass: display.Display = display.getDefaultDisplaySync();constdensity = displayClass.densityDPI;constscreenWidthVp = density >0? displayClass.width / density *160:360;this.isTabletMode = screenWidthVp >=600;这让同一套代码能在不同设备上呈现不同密度:
- 手机:单列、轻量、适合随手查。
- 平板:更大字号、更高 TabBar、更宽详情页,适合系统学习。
- 横屏:周期表这类 18 列信息可以展示得更完整。
此外,项目还配置了备份能力:
{"allowToBackupRestore":true}这对学习类 App 很重要。用户的收藏、错题、成就、学习天数都属于长期积累的数据,一旦换设备或重装,如果完全丢失,学习连续性会被打断。
六、收藏与错题:跨设备流转的核心数据
项目的收藏管理器用AppStorage存储数据,并通过版本号触发 UI 刷新:
functionwriteFavorites(items: FavoriteItem[]): void {AppStorage.setOrCreate(STORAGE_KEY, JSON.stringify(items)); const version = (AppStorage.get<number>(STORAGE_VERSION_KEY) ??0) +1;AppStorage.setOrCreate(STORAGE_VERSION_KEY,version); }错题集也采用轻量存储:
exportfunctionaddWrongQuestionId(id:number): void { const ids = readIds();if(!ids.includes(id)) { ids.push(id); writeIds(ids); } }这些数据非常适合做跨设备同步或备份恢复:
- 收藏:用户主动标记的长期兴趣。
- 错题:用户短期学习弱点。
- 成就:用户持续使用的激励系统。
- 学习统计:可以生成个性化学习报告。
如果后续做全场景,可以把它们拆成多个数据域,而不是全部混在一个大 JSON 里。这样更方便做版本迁移和局部同步。
七、近场快传文章里的落地写法
如果你要把这个主题写成 CSDN 文章,不建议只写“鸿蒙支持近场快传”。更推荐按照下面逻辑展开:
- 先说明教育 App 的真实分享场景。
- 再说明项目中已有的分享入口和详情页参数路由。
- 然后定义统一的
SharePayload。 - 最后扩展到系统分享、近场快传、跨设备打开。
这样文章会显得有项目基础,而不是纯概念。
可以这样总结:
近场快传不是简单传文本,而是把学习内容变成“可识别、可跳转、可复习”的结构化对象。
八、实况窗文章里的落地写法
实况窗不要什么都放,最适合展示“正在发生、状态会变化、用户关心结果”的内容。
在本项目中,限时挑战最合适:
- 正在进行。
- 有倒计时。
- 有进度。
- 有结果。
- 用户切出 App 后仍然关心。
实况窗展示内容建议控制在三行以内:
- 标题:化学限时挑战。
- 进度:第 3/10 题。
- 状态:剩余 42 秒,对 2 错 0。
复杂解析、题干、选项不适合放进实况窗。实况窗负责提醒和回流,完整答题仍然回到 App 内完成。
九、总结
「化学视界」当前虽然是一个离线学习工具,但它的模块结构很适合扩展到鸿蒙全场景:
- 📤 元素、方程式、知识点可以做近场快传。
- ⏱️ 限时挑战可以接入实况窗。
- 📱 手机和平板可以共享同一套响应式页面。
- ☁️ 收藏、错题、成就可以通过备份能力延续学习数据。
- 🔗 路由参数可以让分享内容被精准打开。
所以这类项目写鸿蒙新特性文章时,不必强行追求“大而全”。只要从一个真实学习场景切入,把系统能力和项目结构连接起来,就能写出既有技术含量又有产品思考的内容。🌈