鸿蒙开发5.0案例分析:一多开发实例(商务办公)
本文从目前流行的垂类市场中,选择商务办公类应用作为典型案例,详细介绍 “一多” 在实际开发中的应用。主要包含入口、备忘录、笔记汇总、笔记、日历等典型页面。核心功能:侧边栏显隐 :监听断点变化,设置 SideBarContainer组件 的SideBarContainerType属性或改变showSideBar属性参数,实现侧边栏根据不同断点显示隐藏及显示类型的变化。
📝往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)
🚩 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
🚩 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
🚩 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
🚩 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
🚩 记录一场鸿蒙开发岗位面试经历~
📃 持续更新中……
概述
本文从目前流行的垂类市场中,选择商务办公类应用作为典型案例,详细介绍 “一多” 在实际开发中的应用。主要包含入口、备忘录、笔记汇总、笔记、日历等典型页面。
-
核心功能:
侧边栏显隐 :监听断点变化,设置 SideBarContainer组件 的SideBarContainerType属性或改变showSideBar属性参数,实现侧边栏根据不同断点显示隐藏及显示类型的变化。
分栏布局 :分栏布局通过 Navigation 实现,监听断点变化,根据不同断点或状态改变Navigation的mode属性,实现单双栏切换的效果。
宫格卡片 :用网格布局 Grid组件 ,在不同断点下将父组件分为不同列数,来实现自适应布局的占比能力。
-
关键场景:
入口-多实例:监听断点变化,设置 List组件 的listDirection属性在断点为sm时为Vertical纵向展示,其余断点为Horizontal横向展示,实现入口组件根据不同断点横纵排列不同的效果。使用 startAbility 实现点击子组件时拉起新实例的效果。
备忘录-侧边栏显隐:监听断点变化,设置 SideBarContainer组件 的SideBarContainerType属性或改变showSideBar属性参数,实现侧边栏根据不同断点显示隐藏及显示类型的变化。
日历-navigation的单双栏变化:监听断点变化,根据不同断点或状态改变 Navigation 的mode属性,实现单双栏效果切换的效果。
UX设计
本示例中的商务办公应用包含入口、备忘录、笔记汇总、笔记、日历等页面。以平板端为例,应用的基本业务逻辑如下所示。

架构设计
HarmonyOS的分层架构主要包括三个层次:产品定制层、基础特性层和公共能力层,为开发者构建了一个清晰、高效、可扩展的设计架构。
页面开发
本章介绍商务办公类应用中如何使用”一多”的布局能力,完成页面层级的一套页面、多端适配。下文将从不同页面展开,介绍每个页面区域使用到具体的布局能力,帮助开发者从零到一进行商务办公类应用的开发。
入口
- 将入口页划分为2个部分,效果图如下:
| 示意图 | sm | md | lg | 2in1 |
|---|---|---|---|---|
| 效果图 | ![]() |
![]() |
![]() |
![]() |
- 对其中的各个区域分析使用的一多能力,实现方案如下表:
| 区域编号 | 简介 | 实现方案 |
|---|---|---|
| 1 | 标题 | Text组件实现。 |
| 2 | 多实例入口 | 设置 List组件 的listDirection属性在断点为sm时为Vertical纵向展示,其余断点为Horizontal横向展示,同时点击子组件使用 startAbility 拉起新实例。 |
- 多实例入口
监听断点变化,设置 List组件 的listDirection属性在断点为sm时为Vertical纵向展示,其余断点为Horizontal横向展示,实现入口组件根据不同断点横纵排列不同的效果。使用 startAbility 实现点击子组件时拉起新实例的效果。
// Index.ets
// ...
Column() {
// ...
List(){
ForEach(this.directory, (item: DirectoryItem, index: number) => {
ListItem(){
Column() {
// ...
}
// ...
.onClick(() => {
if (index === CommonConstants.COMMON_ZERO) {
let want: Want = {
bundleName: 'com.example.businessoffice',
abilityName: 'SecondAbility'
};
let option: StartOptions = { displayId: CommonConstants.COMMON_ZERO };
(getContext(this) as common.UIAbilityContext).startAbility(want, option);
} else {
let want: Want = {
bundleName: 'com.example.businessoffice',
abilityName: 'ThirdAbility'
};
let option: StartOptions = { displayId: CommonConstants.COMMON_ZERO };
(getContext(this) as common.UIAbilityContext).startAbility(want, option);
}
})
}
// ...
}, (item: DirectoryItem) => JSON.stringify(item))
}
// ...
.listDirection(this.breakPoint === CommonConstants.BREAK_POINT_SM ? Axis.Vertical : Axis.Horizontal)
}
// ...
备忘录
- 将备忘录页划分为6个部分,效果图如下:
| 示意图 | sm | md | lg | 2in1 |
|---|---|---|---|---|
| 效果图 | ![]() |
![]() |
![]() |
![]() |
- 对其中的各个区域分析使用的一多能力,实现方案如下表:
| 区域编号 | 简介 | 实现方案 |
|---|---|---|
| 1 | 侧边栏 | 监听断点变化,设置 SideBarContainer组件 的SideBarContainerType属性在断点为lg时为Embed,其余断点为Overlay,实现侧边栏根据不同断点显示类型变化的效果 |
| 2 | 侧边栏显隐控件 | 监听断点变化,设置SideBarContainer组件的showSideBar属性,实现侧边栏根据不同断点显示隐藏的效果。 |
| 3 | navigation导航页 | 通过 Navigation 路由栈 NavPathStack ,将NavDestination页面信息入栈,实现NavDestination页面的展示。 |
| 4 | navigation内容页 | NavDestination页面信息。 |
| 5 | navigation内容页-控制按钮 | 给控制按钮添加onClick事件,通过自定义变量notesNavMode改变 Navigation 中mode属性的值,控制单双栏的变化,并通过自定义变量sideBarStatus改变 SideBarContainer组件 中showSideBar属性的值,控制侧边栏的显隐,实现内容页全屏展示或退出全屏的效果。 |
| 6 | 按钮组件 | 监听断点变化,不同断点展示的位置不同。 |
- 侧边栏显示类型变化
监听断点变化,同时设置 SideBarContainer组件 的SideBarContainerType属性在断点为lg时为Embed,其余断点为Overlay,实现侧边栏根据不同断点显示类型变化的效果。
// NotesPages.ets
// ...
SideBarContainer(this.breakPoint === CommonConstants.BREAK_POINT_LG ? SideBarContainerType.Embed : SideBarContainerType.Overlay) {
// ...
}
// ...
-
侧边栏显隐变化
监听断点变化,同时设置 SideBarContainer组件 的showSideBar属性,实现侧边栏根据不同断点显示隐藏的效果。
// NotesPages.ets
// ...
SideBarContainer(this.breakPoint === CommonConstants.BREAK_POINT_LG ? SideBarContainerType.Embed : SideBarContainerType.Overlay) {
// ...
}
// ...
.showSideBar(this.breakPoint === CommonConstants.BREAK_POINT_LG ? this.arrowStatus : false)
// ...
-
navigation内容页-控制按钮
给控制按钮添加onClick事件,通过自定义变量notesNavMode改变 Navigation 中mode属性的值,控制单双栏的变化,并通过自定义变量sideBarStatus改变 SideBarContainer组件 中showSideBar属性的值,控制侧边栏的显隐,实现内容页全屏展示或退出全屏的效果。
// NotesPagesC.ets
// ...
Row() {
if(this.arrowStatus && this.breakPoint !== CommonConstants.BREAK_POINT_SM){
Column() {
// ...
}
// ...
.onClick(()=>{
this.notesNavMode = NavigationMode.Stack;
this.arrowStatus = false;
this.sideBarStatus = false;
})
} else {
Column() {
// ...
}
// ...
.onClick(()=>{
if (this.breakPoint === CommonConstants.BREAK_POINT_SM) {
this.notesPageInfos.pop();
} else {
this.notesNavMode = NavigationMode.Split;
this.arrowStatus = true;
}
this.sideBarIsShown = true;
if (this.breakPoint === CommonConstants.BREAK_POINT_LG) {
this.sideBarStatus = true;
}
})
}
// ...
}
// ...
- 整个页面使用的是 分栏布局 ,点击navigation导航页的某一备忘清单时,可分栏显示备忘内容,该功能在 一多开发实例(银行理财)中有详细介绍。
笔记汇总
- 将笔记汇总页划分为4个部分,效果图如下:
| 示意图 | sm | md | lg | 2in1 |
|---|---|---|---|---|
| 效果图 | ![]() |
![]() |
![]() |
![]() |
- 对其中的各个区域分析使用的一多能力,实现方案如下表:
| 区域编号 | 简介 | 实现方案 |
|---|---|---|
| 1 | 侧边栏 | 监听断点变化,设置 SideBarContainer组件 的SideBarContainerType属性在断点为lg时为Embed,其余断点为Overlay,实现侧边栏根据不同断点显示类型变化的效果。 |
| 2 | 侧边栏显隐控件 | 监听断点变化,设置SideBarContainer组件的showSideBar属性,实现侧边栏根据不同断点显示隐藏的效果。 |
| 3 | 标题栏 | 空白部分使用 Blank组件 填充,实现拉伸能力。2in1设备需设置setWindowDecorVisible接口,隐藏标题栏后避让系统绘制的右上角三键区域。 |
| 4 | 笔记汇总 | 使用网格布局 Grid组件,在不同断点下将父组件分为不同列数,来实现自适应布局的占比能力 |
- 整个页面使用的是 宫格卡片,点击某一个笔记时,可打开笔记实例。
笔记
- 将笔记页划分为3个部分,效果图如下:
| 示意图 | sm | md | lg | 2in1 |
|---|---|---|---|---|
| 效果图 | ![]() |
![]() |
![]() |
![]() |
- 对其中的各个区域分析使用的一多能力,实现方案如下表:
| 区域编号 | 简介 | 实现方案 |
|---|---|---|
| 1 | 标题栏 | 点击加号,增加 Tabs标签 及 TabContent,实现多实例的效果,空白部分使用 Blank组件 填充,实现拉伸能力。 |
| 2 | 编辑按钮 | 监听断点变化,改变 List组件 下子组件的间隔宽度,同时设置固定宽度,当List组件下的Tabs内容超过设定宽度时隐藏部分Tabs,延伸显示更多。 |
| 3 | 笔记内容 | Tabs标签 下的 TabContent。 |
日历
- 将日历页划分为6个部分,效果图如下:
| 示意图 | sm | md | lg | 2in1 |
|---|---|---|---|---|
| 效果图 | ![]() |
![]() |
![]() |
![]() |
- 对其中的各个区域分析使用的一多能力,实现方案如下表:
| 区域编号 | 简介 | 实现方案 |
|---|---|---|
| 1 | 侧边栏 | 设置 SideBarContainer组件的SideBarContainerType属性在断点为lg时为Embed,其余断点为Overlay,实现侧边栏根据不同断点显示类型变化的效果。 |
| 2 | 侧边栏显隐控件 | 设置 SideBarContainer组件 的showSideBar属性,实现侧边栏根据不同断点显示隐藏的效果。 |
| 3 | 标题栏 | 空白部分使用 Blank组件 填充,实现拉伸能力。2in1设备需设置setWindowDecorVisible接口,隐藏标题栏后避让系统绘制的右上角三键区域。 |
| 4 | navigation导航页 | 使用 Grid组件 设置columnsTemplate和rowsTemplate属性,实现五行七列的自适应布局。 通过 Navigation 路由栈NavPathStack,将NavDestination页面信息入栈,并监听断点变化,根据不同断点或状态改变 Navigation 的mode属性,实现单双栏切换及navigation内容页显隐的效果。 |
| 5 | navigation内容页 | NavDestination页面信息。 |
| 6 | navigation控制按钮 | 给控制按钮添加onClick事件,用来改变 Navigation 的mode属性,实现单双栏切换及控制navigation内容页显隐的效果。 |
-
单双栏切换
监听断点的变化,通过控制按钮的点击事件,用来改变 Navigation 的mode属性的变化,实现单双栏切换及navigation内容页显隐的效果,同时监听navigationMode的变化,来控制页面是否跳转。
// CalendarPage.ets
// ...
if (this.breakPoint !== CommonConstants.BREAK_POINT_SM) {
// ...
Column() {
// ...
}
// ...
.onClick(() => {
if (this.navMode === NavigationMode.Split) {
this.navMode = NavigationMode.Stack;
} else if (this.navMode === NavigationMode.Stack && this.selectedItem.isTrip) {
this.navMode = NavigationMode.Split;
}
})
}
// ...
Navigation(this.calendarPageInfos) {
CalendarView()
}
.navDestination(this.pageMap)
.mode(this.breakPoint === CommonConstants.BREAK_POINT_SM ? NavigationMode.Stack : this.navMode)
// ...
.onNavigationModeChange((mode: NavigationMode) => {
if (this.breakPoint === CommonConstants.BREAK_POINT_SM || mode === NavigationMode.Stack) {
this.calendarPageInfos.clear();
} else if (mode === NavigationMode.Split) {
this.calendarPageInfos.pushPath({ name: this.selectedItem.date, param: this.selectedItem }, false);
}
})
// ...
- 整个页面使用的是 分栏布局 ,点击navigation导航页的某一日期时,可分栏显示行程内容,该功能在 一多开发实例(银行理财)中有详细介绍。
更多推荐






















所有评论(0)