📝往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

🚩 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

🚩 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

🚩 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

🚩 鸿蒙岗位需求突增!移动端、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导航页的某一日期时,可分栏显示行程内容,该功能在 一多开发实例(银行理财)中有详细介绍。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐