🚀🚀🚀🚀
鸿蒙生态为开发者提供海量的 HarmonyOS 模板/组件,助力开发效率原地起飞
★一键直达生态市场组件&模板市场 , 快速应用DevEco Studio插件市场集成组件&模板 ★
工作生活小帮手,笔记应用可以集中管理零散信息、提高信息获取和协作效率。
本期案例介绍如何快速基于模板开发一款笔记应用
👉覆盖 20+行业,点击查看往期案例汇总贴,点击收藏!一键三连!常看常新!
【第 6 期】商务办公· 笔记应用
一、 概述
1. 行业洞察
1) 行业诉求:
用户忠诚度低:工具性产品功能相对单一,缺乏互动入口,用户黏性很低。
同质化严重:开源框架等技术的发展降低了开发门槛,许多工具应用在功能上高度重叠,尤其是 SaaS 工具市场,各种功能相似、定位重叠的产品层出不穷,导致用户选择困难,开发者也难以脱颖而出。
个性化需求满足难度大:随着用户需求的不断变化和多样化,工具应用需要覆盖的场景也越来越多,但很多工具提供的是通用功能,无法快速满足客户的各种差异化需求,尤其是一些静态分析工具等专业工具,用户难以开发自定义规则,对误报和漏报的规则也无法快速修改。
2) 行业常用三方 SDK
说明:“以上三方库及链接仅为示例,三方库由三方开发者独立提供,以其官方内容为准”
极光安全认证 SDK 腾讯优量汇 SDK 美数AdMate SDK 穿山甲广告 SDK 腾讯图灵盾风险识别 SDK 支付宝 SDK Thinking SDK 七牛云存储 SDK 友盟移动统计 SDK Utdid 腾讯微信 SDK 腾讯QQ SDK
2. 行业案例概览(下载模板)
基于以上行业分析,本期将介绍鸿蒙生态市场商务办公类行业模板——笔记应用模板,为行业提供常用功能的开发案例,模板主要分首页、我的两大模块。
Stage 开发模型 + 声明式 UI 开发范式。
分层架构设计+ 组件化拆分,支持开发者在开发时既可以选择完整使用模板,也可以根据需求单独选用其中的业务组件。
本模板已集成账号服务,只需做少量配置和定制即可快速实现华为账号一键登录。
本模板主要页面及核心功能如下所示:
笔记模板
|-- 首页
| |-- 搜索
| |-- 笔记分类
| | |-- 新建分类
| | |-- 重命名
| | └-- 删除分类
| |-- 排序
| | |-- 按创建时间排序
| | └-- 按修改时间排序
| |-- 笔记列表
| | |-- 复制内容
| | |-- 移动到其他分类
| | └-- 删除
| |-- 创建笔记
| | |-- 保存
| | └-- 分享笔记
| └-- 编辑笔记
| |-- 保存
| └-- 分享笔记
└-- 我的
|-- 用户信息
| |-- 华为账号一键登录
| └-- 头像昵称修改
└-- 回收站
| |-- 搜索笔记
| |-- 恢复笔记
| └-- 彻底删除
└-- 设置
|-- 隐私协议
|-- 保密设置
| |-- 手势密码
| └-- 指纹解锁
└-- 退出登录
复制代码
二、 应用架构设计
1. 分层模块化设计
① 本实践暂时只支持直板机,为单 HAP 包形式,包含路由根节点、底部导航栏等。
① 本实践的基础特性层将应用底部导航栏的每个选项拆分成一个独立的业务功能模块。
② 每个功能模块都具备高内聚、低耦合、可定制的特点,支持产品的灵活部署。
① 本实践的公共能力层分为公共基础能力和行业组件,均打包为 HAR 包被基础特性层的业务模块引用。
② 公共基础能力包含日志、文件处理等工具类,公共类型定义,网络库,以及弹窗、加载等公共组件。
③ 可分可合组件将包含行业特点、可完全自闭环的能力抽出独立的组件模块,支持开发者在开发中单独集成使用,详见业务组件设计章节。
2. 业务组件设计
为支持开发者单独获取特定场景的页面和功能,本模板将功能完全自闭环的部分能力抽离出独立的行业组件模块,不依赖公共基础能力包,开发者可以单独集成,开箱即用,降低使用难度。
三、 行业场景技术方案
1.富文本笔记编辑
1) 场景说明
2) 技术方案
2.笔记分类管理
1) 场景说明
2) 技术方案
3.搜索功能
1) 场景说明
用户可在首页通过搜索框输入关键词进行实时搜索,支持在正常笔记和回收站笔记中进行全文检索,搜索结果实时展示。
2) 技术方案
四、 模板代码
1. 工程结构(下载模板)
详细代码结构如下所示:
Notes
|- common // 公共层
| |- datasource/src/main/ets/ // 公共资源
| | |- CategoryService.ets // 分类服务
| | |- Data.ets // mock数据
| | |- Model.ets // 建立模型
| | └- NoteService.ets // 笔记服务
| └- utils/src/main/ets // 公共组件模块(hsp)
| |- constants
| | CommonConstants.ets // 公共常量
| | DateConstants.ets // 日期格式化常量
| └- utils // 工具类
| AccountUtil.ets // 账号
| AppUtil.ets // 应用
| DateUtil.ets // 日期处理
| LogUtil.ets // 日志工具
| ObjectUtil.ets // 对象工具
| ShowToast.ets // 吐司
| StringUtil.ets // 字符串工具
|
|- components // 公共组件
| |- richeditor/src/main/ets/ // 富文本组件
| | |- common
| | | Constants.ets // 公共常量
| | |- components
| | | RichEditorArea.ets // 富文本编辑
| | | SnapshotPreview.ets // 截图预览
| | |- model
| | | AlignmentInfo.ets // 编辑富文本框段落选项
| | └- util
| | CommonUtils.ets // 常用(沉睡/截图)
| | ControllerUtil.ets // 本项目使用
| | ImageUtils.ets // 图片处理
| | PickerUtil.ets // 选择、保存图片
| | PopupUtils.ets // 截图计算
| | RichEditorUtil.ets // 富文本编辑器工具类
| |
| └- secretlock/src/main/ets/ // 应用密码设置组件
| |- components
| | SecretLockSwitch.ets // 密码设置开关
| |- model
| | AuthOptions.ets // 认证参数类
| | SecretLock.ets // 密码锁-保密设置(持久化)
| |- pages
| | DrawLock.ets // 密码设置绘制页面
| └- util
| AuthUtil.ets // 生物识别认证工具类
|
└- product/phone
└---src/main/ets
|- common
| LoginConstants.ets // 登录常量
|- components
| RightArrow.ets // 右箭头
|- entryability
| EntryAbility.ets // 主页面
└- pages
mine // 我的-相关页面
|- MineView.ets // 我的页面入口
|- PrivacyAgreement.ets // 隐私协议(隐私政策)
|- QuickLoginPage.ets // 一键登录
|- SecretSetting.ets // 保密设置
|- Setting.ets // 设置
|- Trash.ets // 回收站
└- UserInfoPage.ets // 用户信息
EditorCategory.ets // 编辑分类
EditNotes.ets // 编辑笔记
Index.ets // 入口页面
复制代码
2. 关键代码解读
本篇代码非应用的全量代码,只包括应用的部分能力的关键代码。
1)笔记多选管理
// 笔记卡片长按事件处理
handleLangPress(item: Note) {
// 非多选状态下生效
if (!this.selectedController.isCtrl) {
this.selectedController.isCtrl = true;
item.isSelected = true;
this.selectedController.selectedCount = 1;
}
}
// 全选功能实现
handleSelectAll() {
if (this.selectedController.selectedCount === this.noteList.length) {
this.noteList.forEach(item => item.isSelected = false);
this.selectedController.selectedCount = 0;
} else {
this.noteList.forEach(item => item.isSelected = true);
this.selectedController.selectedCount = this.noteList.length;
}
}
// 多选工具栏构建
@Builder
toolBarBuilder(){
if (this.selectedController.isCtrl){
Row(){
ForEach(toolBarList, (item: ToolBar) => {
Column({ space: 5 }){
Image(item.icon)
.width(24)
.height(24)
Text(item.name)
.fontSize(10)
.fontColor($r('sys.color.font_secondary'))
}
.onClick(() => {
this.handleToolBarClick(item.name)
})
}, (item: ToolBar) => JSON.stringify(item))
}
.margin({ top: 10 })
.padding({ bottom: 10 })
.justifyContent(FlexAlign.SpaceAround)
.width('100%')
.height(70)
.backgroundColor($r('sys.color.comp_background_list_card'))
}
}
复制代码
2)富文本编辑器控制
// 富文本编辑器控制器
richEditorController: RichEditorController = RichEditorController.instance;
// 撤销重做功能实现
@Builder
toolBar() {
Row({ space: 12 }) {
Image(this.richEditorController.currentIndex < 1 ?
$r('app.media.undo_expire') : $r('app.media.undo_effect'))
.width(40)
.height(40)
.onClick(() => {
this.richEditorController.onDo(); // 撤销
});
Image(this.richEditorController.currentIndex >= this.richEditorController.historyRecordArray.length - 1 ?
$r('app.media.redo_expire') : $r('app.media.redo_effect'))
.width(40)
.height(40)
.onClick(() => {
this.richEditorController.reDo(); // 重做
});
}
}
// 内容复制功能
copyNoteText() {
let copyText = this.currentNote?.description || '';
let plainTextData = new unifiedDataChannel.UnifiedData();
let plainText = new unifiedDataChannel.PlainText();
plainText.details = {
key: 'delayPlaintext',
value: copyText,
};
plainText.textContent = copyText;
plainText.abstract = 'delayTextContent';
plainTextData.addRecord(plainText);
let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
systemPasteboard.setUnifiedData(plainTextData);
}
复制代码
3)分类管理实现
// 分类右滑操作菜单
@Builder
categoryEnd(item: Category){
Row() {
Image($r('app.media.edit_category'))
.width(40)
.height(40)
.margin({ left: 16, right: 16})
.onClick(() => {
this.isEditCategoryName = true;
this.categoryId = item.id;
// 打开编辑分类弹窗
})
Image($r('app.media.delete_category'))
.width(40)
.height(40)
.onClick(() => {
this.categoryId = item.id;
// 打开删除分类弹窗
})
}
.width(112)
.height(48)
}
// 分类删除对话框
@ComponentV2
struct DeleteCategoryDialog {
@Param @Require params: DeleteCategoryParam;
noteService: NoteService = NoteService.instance;
categoryService: CategoryService = CategoryService.instance;
build() {
Column({ space: 30 }) {
// 仅删除分类选项
Row() {
Text('仅删除分类')
.fontSize(16)
.onClick(() => {
this.noteService.moveNotesCategory(this.params.categoryId);
this.categoryService.deleteCategoryById(this.params.categoryId);
});
}
// 删除分类和笔记选项
Row() {
Text('删除分类和笔记')
.fontSize(16)
.fontColor(Color.Red)
.onClick(() => {
let notes = this.noteService.getNoteList(this.params.categoryId);
notes.forEach((item) => {
this.noteService.deleteNote(item.id);
});
this.categoryService.deleteCategoryById(this.params.categoryId);
});
}
}
}
}
复制代码
4)响应式布局适配
// 断点响应式样式定义
@Styles
topAreaStyle() {
.width('100%')
.padding(new BreakpointType<Padding>({
sm: {
top: 12,
bottom: 20,
left: $r('sys.float.padding_level8'),
right: $r('sys.float.padding_level8'),
},
md: {
top: 12,
bottom: 20,
left: $r('sys.float.padding_level12'),
right: $r('sys.float.padding_level12'),
},
lg: {
top: 12,
bottom: 20,
left: $r('sys.float.padding_level16'),
right: $r('sys.float.padding_level16'),
},
}).getValue(this.globalInfo.currentBreakpoint));
}
// 不同视图模式适配
@Builder
showNoteList() {
if (this.noteSearchController.isSearching && this.noteList.length === 0) {
SearchNoResult()
}
if (!this.noteSearchController.isSearching && this.noteList.length === 0){
EmptyNotes()
} else if (this.showListType === SHOW_METHOD_ENUM.normalList) {
this.cardList() // 列表视图
} else {
this.waterCardList() // 瀑布流视图
}
}
// 瀑布流布局实现
@Builder
waterCardList() {
Column() {
WaterFlow() {
LazyForEach(this.dataList, (item: Note) => {
FlowItem() {
this.cardItem(item, 9) // 9行文本显示
}
.width('100%')
.gesture(
LongPressGesture({ repeat: false, fingers: 1, duration: 500 })
.onAction((event: GestureEvent|undefined) => {
if(event){
this.handleLangPress(item)
}
})
)
}, (item:Note) => item.id)
}
.columnsTemplate('1fr 1fr') // 两列布局
.columnsGap(obtainGutter(this.globalInfo.currentBreakpoint, 'WaterFlow'))
.rowsGap(16)
}
}
复制代码
以上代码展示了商务笔记应用的核心功能实现,包括多选管理、富文本编辑、分类管理和响应式布局等关键技术方案。
3. 模板集成
本模板提供了两种代码集成方式,供开发者自由选用。
1) 整体集成(下载模板)
开发者可以选择直接基于模板工程开发自己的应用工程。
① 通过 IDE 插件创建模板工程,开发指导。
② 通过生态市场下载源码, 下载模板。
③ 通过开源仓访问源码,仓库地址。
将 commons/lib_common/src/main/ets/httprequest/HttpRequestApi.ets 文件中的 mock 接口替换为真实的服务器接口。
在 commons/lib_common/src/main/ets/httprequest/HttpRequest.ets 文件中将云侧开发者自定义的数据结构转换为端侧数据结构。
根据自己的业务内容修改模板,进行定制化开发。
2) 按需集成
若开发者已搭建好自己的应用工程,但暂未实现其中的部分场景能力,可以选择取用其中的业务组件,集成在自己的工程中。
①通过 IDE 插件下载组件源码。开发指导
②通过生态市场下载组件源码。 下载地址
以上是第 6 期“商务办公-笔记应用”行业案例的内容,更多行业敬请期待~
欢迎下载使用行业模板“点击下载”,若您有体验和开发问题,或者迫不及待想了解 XX 行业的优秀案例,欢迎在评论区留言,小编会快马加鞭为您解答~
同时诚邀您添加下方二维码加入“组件模板活动社群”,精彩上新 &活动不错过!
👉 HarmonyOS 官方模板优秀案例系列持续更新, 点击查看往期案例汇总贴,欢迎收藏本帖!
👉【互动有礼】邀请你成为 HarmonyOS 官方模板产品经理,优化方案由你制定!点击参加
👉 HarmonyOS 组件模板相关推荐:鸿蒙应用开发者激励计划 2025,点击查看
评论