# HarmonyOS NEXT 体验官 # XBoard作品技术详解 原创

时空未宇
发布于 2024-8-15 09:02
浏览
1收藏

介绍

​ XBoard是一款集“篮球战术板”、“协作互动板”、“便携手写板”等易用画板类工具为一身的作品。

​ 篮球战术板具有添加队员,自由笔迹,战术讲解等特色功能。
​ 协作互动板目标服务于亲子互动,合作共创的场景。
​ 便携手写板可提供草稿验算,轮播文字展示等服务。

XBoard具有灵活性、便利性、教育价值、环保特性和技术集成等优势。
截止目前,已拥有“篮球战术板”、“协作互动板”、“便携手写板”等功能。
目标是将鸿蒙的特性细腻且恰如其分地融入到实际使用场景中。

本作品旨在适应不同场景、用户需求和业务模式的变化。
以实际功能实现了有效的全场景匹配。
XBoard以用户为中心,深入理解并预测用户在各种场景下的需求,
设计符合用户习惯、提升用户体验的服务。
譬如:协作互动板可以在亲子教育,辅导课业的活动中大放异彩,家长在一部设备上出题,
孩子可以在另一部设备上作答。而后家长可依据完成质量给出评分,
整个过程顺畅且优质。使用体验佳。

效果预览

# HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区 # HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区
# HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区 # HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区
# HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区 # HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区
# HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区 # HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区
# HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区 # HarmonyOS NEXT 体验官 # XBoard作品技术详解-鸿蒙开发者社区

知识点

1. 分层架构设计
2. 模块化设计
3. Canvas组件
4. EventHub

工程目录

├──commons                         // 公共能力层
│  ├──datastore					   // 数据管理
│  ├──uicomponents				   // 公共UI组件
│  └──utils					       // 工具库
├──features                        // 基础特性层
│  ├──collaborating			       // 协作互动板
│  ├──portable					   // 便携手写板
│  └──tactical					   // 篮球战术板
└──products                        // 产品定制层
   └──phone						   // 应用的入口

具体实现

​ 随着应用规模的扩大和业务需求的复杂化,代码的复杂度相应提升。因此,良好的应用架构设计变得尤为重要,架构设计的目的是让应用更易于维护、扩展和测试。

  • 分层架构设计:将应用划分为产品定制层、基础特性层和公共能力层,可以降低层间的依赖性,从而提升代码的可维护性。通过分层架构设计进一步明确了每层的职责和层间的交互机制,为开发者呈现了一个清晰且结构化的开发框架。

  • 模块化设计:将应用分解为多个功能模块,其中每个模块负责执行特定的功能。通过模块化设计提高了代码的可理解性和可复用性,使应用的扩展和维护变得更为简便,同时降低了系统各部分之间的耦合度。

    XBoard作品主要分为三个功能模块,每人负责各自模块开发,互不影响,大大降低了各部分之间的耦合度,同时把公共组件抽出放到公共能力层,让各模块使用,比如标题栏组件,同时隐私协议框,制作为三方库,方便之后项目使用。

1. 首页实现

首页主要显示隐私协议和引用标题组件和内容组件。

privacyDialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogPrivacy({
      openPrivacy: openPrivacyPage
    }),
    autoCancel: false,
    alignment: DialogAlignment.Center,
    customStyle: true
  })

  onPageShow() {
    preferencesUtil.getChangePrivacy().then((value) => {
      if (!value) {
        this.privacyDialogController.open()
      }
    })
  }
  onPageHide() {
    this.privacyDialogController.close()
  }
  aboutToDisappear() {
    this.privacyDialogController.close()
  }
  // 结束显示隐私协议对话框
build() {
    Column() {
      Title()
      Content()
    }
    .width(CommonConstants.FULL_PERCENT)
    .height(CommonConstants.FULL_PERCENT)
    .linearGradient({
      // 0点方向顺时针旋转为正向角度,线性渐变起始角度的默认值为180°
      colors: [
        [0xDCFFF1, 0.0], // 颜色断点1的颜色和比重,对应组件在180°方向上的起始位置
        [0xFFFFFF, 1.0], // 颜色断点2的颜色和比重,对应组件在180°方向上的终点位置
      ]
    })
  }

标题组件

Row() {
      Image($r('app.media.help'))
        .objectFit(ImageFit.Contain)
        .width(px2vp(72))
        .height(px2vp(72))
      Blank()
      Image($r('app.media.about'))
        .objectFit(ImageFit.Contain)
        .width(px2vp(60))
        .height(px2vp(69))
    }
    .width(CommonConstants.FULL_PERCENT)
    .padding(px2vp(72))

内容组件,同时也是三个模块的入口,使用RelativeContainer布局

RelativeContainer() {
      Image($r('app.media.tactical'))
        .offset({ y: -px2vp(470)})
        .width(px2vp(759))
        .height(px2vp(732))
        .objectFit(ImageFit.Contain)
        .id('tactical')
        .alignRules({
          center: {anchor: '__container__', align: VerticalAlign.Center},
          middle: {anchor: '__container__', align: HorizontalAlign.Center}
        })
        .onClick(() => {
          console.info(`xx 点击篮球战术板`)
          router.pushNamedRoute({
            name: 'tacticalPage'
          })
        })
      Image($r('app.media.portable'))
        .offset({ x: -px2vp(265), y: -px2vp(10)})
        .width(px2vp(759))
        .height(px2vp(732))
        .objectFit(ImageFit.Contain)
        .id('portable')
        .alignRules({
          top: {anchor: 'tactical', align: VerticalAlign.Top},
          middle: {anchor: '__container__', align: HorizontalAlign.Center}
        })
        .onClick(() => {
          console.info(`xx 点击便携手写板`)
          router.pushNamedRoute({
            name: 'portablePage'
          })
        })
      Image($r('app.media.collaborating'))
        .offset({ x: px2vp(265), y: -px2vp(10)})
        .width(px2vp(759))
        .height(px2vp(732))
        .objectFit(ImageFit.Contain)
        .id('collaborating')
        .alignRules({
          top: {anchor: 'tactical', align: VerticalAlign.Top},
          middle: {anchor: '__container__', align: HorizontalAlign.Center}
        })
        .onClick(() => {
          console.info(`xx 点击协作互动板`)
          router.pushNamedRoute({
            name: 'collaboratingPage'
          })
        })
    }
    .width(CommonConstants.FULL_PERCENT)
    .height(CommonConstants.FULL_PERCENT)
2. 篮球战术板模块

​ 主要有画板组件和工具栏组件

      Column() {
        // 画板
        DrawBoard({
          strokeStyle: $strokeStyle,
          isPaintBtn: $isPaintBtn,
          attackArray: this.attackArray,
          defendArray: this.defendArray
        })
        // 底部工具栏
        ToolBar({
          strokeStyle: $strokeStyle,
          isPaintBtn: $isPaintBtn,
          attackArray: this.attackArray,
          defendArray: this.defendArray,
          colorArray: this.colorArray,
          changeBgImage: (param: string) => {
            console.info('xx 点击底部栏设置按钮')
            this.changeBgImage(param)
          },
          clean: () => {
            console.info('xx 点击底部栏清屏按钮')
            this.clean()
          },
          goBack: () => {
            console.info('xx 点击底部栏回退按钮')
            this.goBack()
          }
        })
      }
      .layoutWeight(1)
      .padding(10)
3. 便携手写板模块

​ 主要有画板组件和工具栏组件

Column() {
        // 画板
        DrawBoard({
          strokeStyle: $strokeStyle,
          lineWidth: $lineWidth,
          globalCompositeOperation: $globalCompositeOperation
        })
        // 底部工具栏
        ToolBar({
          strokeStyle: $strokeStyle,
          isPaintBtn: $isPaintBtn,
          isEraserBtn: $isEraserBtn,
          globalCompositeOperation: $globalCompositeOperation,
          clean: () => {
            console.info('xx 点击底部栏清屏按钮')
            this.clean()
          },
          goBack: () => {
            console.info('xx 点击底部栏回退按钮')
            this.goBack()
          }
        })
      }
      .layoutWeight(1)
4. 协作互动板模块

​ 此页面主要使用SideBarContainer侧边栏组件,画板和工具栏组件。

SideBarContainer(SideBarContainerType.Overlay) {
        Column({space: 30}) {
          this.LineWidthComponent()

          Divider()

          this.ColorComponent()

        }.width(CommonConstants.FULL_PERCENT)
        .backgroundColor('#19000000')
        .borderRadius({topRight: 20, bottomRight: 20})
        .padding({ top: 80, bottom: 130, left: 10, right: 10})
        .margin({ top: 10, bottom: 90 })

        Column() {
          // 画板
          DrawBoard({
            strokeStyle: $strokeStyle,
            lineWidth: $lineWidth,
            globalCompositeOperation: $globalCompositeOperation
          })
          // 底部工具栏
          ToolBar({
            strokeStyle: $strokeStyle,
            isPaintBtn: $isPaintBtn,
            isEraserBtn: $isEraserBtn,
            globalCompositeOperation: $globalCompositeOperation,
            changeBgImage: (param: string) => {
              console.info('xx 点击底部栏设置按钮')
              this.changeBgImage(param)
            },
            clean: () => {
              console.info('xx 点击底部栏清屏按钮')
              this.clean()
            },
            goBack: () => {
              console.info('xx 点击底部栏回退按钮')
              this.goBack()
            }
          })
        }
        .layoutWeight(1)
      }
      .controlButton({
        top: px2vp(60),
        left: px2vp(60),
        icons: {
          shown: $r('app.media.list'),
          hidden: $r('app.media.list'),
          switching: $r('app.media.list')
        }
      })
      .showSideBar(false)
      .sideBarWidth(px2vp(237))
      .minSideBarWidth(px2vp(200))
      .maxSideBarWidth(px2vp(250))
      .minContentWidth(0)
      .divider(null)
      .onChange((value: boolean) => {
        console.info('status:' + value)
      })

总结

​ 通过此项目开发,可以学习到分层架构设计、模块化设计开发,学习到Canvas提供画布组件,用于自定义绘制图形,使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象在Canvas组件上进行绘制,绘制对象可以是基础形状、文本、图片等,学习到使用EventHub进行数据通信,EventHub为UIAbility组件提供了事件机制,使它们能够进行订阅、取消订阅和触发事件等数据通信能力。

约束与限制

1.本示例仅支持标准系统上运行,支持设备:华为手机。

2.HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。

3.DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。

4.HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2024-8-15 09:24:21修改
2
收藏 1
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

篮球爱好者表示很赞

1
回复
2024-8-15 10:17:44
回复
    相关推荐