HarmonyOS APP<玩转React>开源教程三十一:示例项目下载功能
第31次:示例项目下载功能
本文讲解
DemoDownloadPage.ets和DemoProjectData.ets。这是项目里很有“作品集”气质的一部分:它把 11 个示例项目做成了可浏览、可筛选、可下载、可分享的内容中心。
这个页面到底在做什么
很多人第一次看到“成品下载”以为只是一个文件列表,但当前页面其实做了完整的展示与操作闭环:
- 项目分类筛选
- 项目预览图展示
- 权限标签提示
- 下载 ZIP 包到本地
- 分享项目压缩包
- 视频教程弹层
一、为什么下载页一定要先把项目数据结构化
DemoProjectData.ets 中每个示例项目都带有完整信息:
idnamedescriptioniconfolderNamezipNameimageNamepermissionscategory
这说明下载页不是“从文件夹临时扫一遍就展示”,而是有明确的数据层。这样做的好处很多:
- UI 展示字段稳定
- 分类筛选更简单
- 权限提示可以直接从数据里读取
- 未来增加新项目只需要补数据项
这就是典型的“页面不猜资源,数据层提前组织好资源信息”。
二、图文结合看一下页面里真实用到的示例图
当前下载页会直接读取 rawfile 中的预览图。你可以先看几个真实素材:



这些图片的存在,让下载页不再只是冷冰冰的文件列表,而是真正能让用户“看到项目长什么样”。这就是图文结合带来的价值。
三、分类筛选为什么做成横向标签条
示例项目一共有多个分类,例如:
- 社交
- 媒体
- 金融
- 健康
- 生活
- 效率
- 购物
- 教育
- 出行
- 设计
这类分类数量不少,但每个分类标签都比较短,所以最适合用横向滚动标签条来承载。这样既不占太多垂直空间,也方便用户快速切换。
这和源码学习、开源项目模块的分类条设计是一脉相承的,说明整个项目在“分类导航”这一模式上保持了统一。
四、项目卡片为什么必须包含预览图和权限标签
当前 ProjectItem(project) 卡片里,除了名称和描述,还展示了:
- 预览图
- 权限标签
- 下载按钮
- 分享按钮
预览图
帮助用户快速判断项目风格和适用方向。
权限标签
告诉用户这个项目可能会涉及哪些系统能力,比如:
- 相机
- 麦克风
- 定位
这一步尤其重要,因为它能帮助用户在下载前建立心理预期。比如看到“相机”权限,就知道这可能是一个拍照类项目;看到“定位”权限,就知道它可能和地图、运动或生活服务有关。
五、下载功能到底做了哪些步骤
downloadProject(project) 的核心流程非常清楚:
- 通过
getContext(this)获取UIAbilityContext - 从
resourceManager读取 rawfile 中的 ZIP 内容 - 计算本地
filesDir下载路径 - 使用
fileIo写入本地文件 - 成功后弹出提示框展示保存路径
这是一条非常典型的鸿蒙本地资源导出链路。教程里一定要按这个真实流程讲,不然读者只会记住“有个下载按钮”,却不知道背后做了什么。
项目里真正执行下载的代码如下:
const context = getContext(this) as common.UIAbilityContext;
const resourceManager = context.resourceManager;
const zipData = await resourceManager.getRawFileContent(project.zipName);
const filesDir = context.filesDir;
const downloadPath = `${filesDir}/${project.zipName}`;
const file = fileIo.openSync(downloadPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
fileIo.writeSync(file.fd, zipData.buffer);
fileIo.closeSync(file);
六、分享功能为什么要先保存本地 ZIP
shareProject(project) 并不是直接把 rawfile 资源拿去分享,而是先把 ZIP 从 rawfile 拷到本地,再通过 ShareService 分享本地文件路径。
这一步说明一个很重要的工程实践:
- 应用内资源不一定能直接拿去给外部系统分享
- 更稳妥的做法是先转存到可访问的本地路径
如果分享失败,页面还会降级为文字提示方案。这种“主方案 + 兜底方案”的设计非常值得学习。
七、视频教程弹层为什么也是这页的一部分
下载页底部还有一个“使用教程”入口,点击后会通过 bindSheet 弹出 TutorialSheet(),里面用 Video 组件播放 使用教程.mp4。
这说明作者不希望用户只把项目下载下来,还希望用户知道怎么使用这些 DEMO。对于学习型资源中心来说,这是非常合理的补充:
- 下载解决“拿到资源”
- 视频解决“知道怎么用”
这就是很典型的图文 + 视频结合式说明页面。
视频教程弹层用到的真实代码如下:
Video({
src: $rawfile('使用教程.mp4'),
controller: this.videoController
})
.width('100%')
.height(220)
.controls(true)
.autoPlay(false)
.onStart(() => {
this.isPlaying = true;
})
八、实操步骤
- 打开下载页,切换几个分类标签。
- 对比不同卡片的预览图、描述和权限标签。
- 点击下载,确认是否能成功保存 ZIP。
- 点击分享,观察正常路径和异常兜底提示。
- 打开视频教程弹层,测试播放、暂停、重播。
只要这几个动作都自己走过一遍,你对这一页的实现思路就会很清楚。
九、本篇常见坑
1. 只有文件名,没有视觉预览
用户很难判断项目是否值得下载。
2. 下载前不提示项目所需权限
会降低用户对项目内容的预期清晰度。
3. 分享时直接拿 rawfile 资源去发
更稳定的方式是先导出到本地。
4. 只有下载,没有教程
这样资源拿到了,但上手成本仍然很高。
九、本篇常见坑
1. 只有文件名,没有视觉预览
用户很难判断项目是否值得下载。
2. 下载前不提示项目所需权限
会降低用户对项目内容的预期清晰度。
3. 分享时直接拿 rawfile 资源去发
更稳定的方式是先导出到本地。
4. 只有下载,没有教程
这样资源拿到了,但上手成本仍然很高。
本篇小结
示例项目下载功能的价值,不只是“导出几个 ZIP 文件”,而是把项目资源做成了一个有预览、有分类、有说明、有下载、有分享、有教程的完整内容中心。
这一页最值得学习的有两点:
- 资源型页面如何做得有吸引力
- 鸿蒙本地资源如何转换成可下载、可分享的文件
课后练习
- 观察
DemoProjectData,思考如果要增加“推荐指数”字段,最适合在下载页的什么位置展示。 - 想一想为什么视频教程适合放在下载页,而不是首页。
- 设计一个“已下载”状态标记方案,说明你会把它存在哪里。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)