鸿蒙HarmonyOS项目实战开发:分布式购物车

简介

分布式购物车demo 模拟的是我们购物时参加满减活动,进行拼单的场景;实现两人拼单时,其他一人添加商品到购物车,另外一人购物车列表能同步更新,且在购物车列表页面结算时,某一人结算对方也能实时知道结算金额和优惠金额。整个操作效果分为3个小动画,

  • 拉起对方用户

show

  • 添加商品到购物车列表

show

  • 购物车列表勾选

show

  • demo效果(HH-SCDAYU200)

show

工程目录

完整的项目结构目录如下

├─entry\src\main
│          │  config.json  应用配置文件
│          │  
│          ├─ets
│          │  └─MainAbility
│          │      │  app.ets  ets应用程序主入口
│          │      │  
│          │      ├─model
│          │      │      ArsData.ets     // 初始化我的页面数据
│          │      │      CommonLog.ets   // 日志类
│          │      │      GoodsData.ets   // 初始化商品信息数据类
│          │      │      MenuData.ets    // 初始化我的页面数据类
│          │      │      RemoteDeviceManager.ets  // 分布式拉起设备管理类
│          │      │      ShoppingCartDistributedData.ets  // 加入购物车分布式数据库
│          │      │      TotalSelectedDistributedData.ets // 结算购物车分布式数据库
│          │      │      
│          │      └─pages
│          │              DetailPage.ets   // 商品详情页面
│          │              HomePage.ets     // 应用首页
│          │              MyPage.ets       // 我的页面
│          │              ShoppingCartListPage.ets  // 购物车列表页面
│     └─resources // 静态资源目录
│         ├─base
│         │  ├─element
│         │  ├─graphic
│         │  ├─layout
│         │  ├─media // 存放媒体资源
│         │  └─profile
│         └─rawfile

开发步骤

1. 新建OpenHarmony ETS项目

在DevEco Studio中点击File -> New Project ->[Standard]Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。 

image-20211124092813545

2. 编写商品展示主页面

image-20211124093106260

效果图如上可以分为两部分

2.1商品列表展示

1)首先在@entry组件入口build()中使用Tabs作为容器,达到排行榜和推荐翻页的效果;

2)再通过List包裹Row布局依次写入Column包裹的三个Text组件和Image组件;

3)并通过Navigator组件实现点击商品跳转到商品详细页功能,页面跳转过程使用pageTransition转场动画

 Tabs() {
        TabContent() {
          GoodsList({ goodsItems: this.goodsItems});
        }
        .tabBar("畅销榜")
        .backgroundColor(Color.White)

        TabContent() {
          GoodsList({ goodsItems: this.goodsItems});
        }
        .tabBar("推荐")
        .backgroundColor(Color.White)
      }
       Navigator({ target: 'pages/DetailPage' }) {
        Row({ space: '40lpx' }) {
          Column() {
            Text(this.goodsItem.title)
              .fontSize('28lpx')
            Text(this.goodsItem.content)
              .fontSize('20lpx')
            Text('¥' + this.goodsItem.price)
              .fontSize('28lpx')
              .fontColor(Color.Red)
          }
          .height('160lpx')
          .width('50%')
          .margin({ left: '20lpx' })
          .alignItems(HorizontalAlign.Start)

          Image(this.goodsItem.imgSrc)
            .objectFit(ImageFit.ScaleDown)
            .height('160lpx')
            .width('40%')
            .renderMode(ImageRenderMode.Original)
            .margin({ right: '20lpx', left: '20lpx' })

        }
        .height('180lpx')
        .alignItems(VerticalAlign.Center)
        .backgroundColor(Color.White)
      }
      .params({ goodsItem: this.goodsItem ,ShoppingCartsGoods:this.ShoppingCartsGoods})
      .margin({ left: '40lpx' })
    }
    // 转场动画使用系统提供的多种默认效果(平移、缩放、透明度等)
  pageTransition() {
    PageTransitionEnter({ duration: 1000 })
      .slide(SlideEffect.Left)
    PageTransitionExit({ duration: 1000  })
      .slide(SlideEffect.Right)
  }
2.2底部导航栏

1)通过Row包裹三个Image组件,并添加onClick点击事件,修改@Consume修饰的变量,从而改变@Provide装饰的变量,再通过条件渲染展示不同的页面内容;

Flex() {
        Image(this.iconPath[0])
          .objectFit(ImageFit.Cover)
          .height('60lpx')
          .width('60lpx')
          .margin({left:'50lpx',right:'40lpx'})
          .onClick(() => {
            this.iconPath[0] = this.iconPathSelectsTmp[0]
            this.iconPath[1] = this.iconPathTmp[1]
            this.iconPath[2] = this.iconPathTmp[2]
            this.currentPage = 1
          })
        Image(this.iconPath[1])
          .objectFit(ImageFit.Cover)
          .height('60lpx')
          .width('60lpx')
          .margin({left:'40lpx',right:'40lpx'})
          .onClick(() => {
            this.iconPath[0] = this.iconPathTmp[0]
            this.iconPath[1] = this.iconPathSelectsTmp[1]
            this.iconPath[2] = this.iconPathTmp[2]
            this.currentPage = 2
            this.remoteData.putData("shopping_cart", this.ShoppingCartsGoods)
          })
        Image(this.iconPath[2])
          .objectFit(ImageFit.Cover)
          .height('60lpx')
          .width('60lpx')
          .margin({left:'40lpx',right:'50lpx'})
          .onClick(() => {
            this.iconPath[0] = this.iconPathTmp[0]
            this.iconPath[1] = this.iconPathTmp[1]
            this.iconPath[2] = this.iconPathSelectsTmp[2]
            this.currentPage = 3
          })
      }
    .margin({top:'20lpx'})
    }
      
      Column() {
          if (this.currentPage == 1) {
            Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.End }) {
              Image($r("app.media.icon_share"))
                .objectFit(ImageFit.Cover)
                .height('60lpx')
                .width('60lpx')
            }
            .width("100%")
            .margin({ top: '20lpx', right: '50lpx' })
            .onClick(() => {
              this.playerDialog.open()
            })

            GoodsHome({ goodsItems: this.goodsItems})
          }
          else if (this.currentPage == 3) {
            //我的
            MyInfo()
          }
        }
3. 编写商品详细页面
3.1顶部滑动组件

1)滑动容器,提供切换子组件显示的能力;

Swiper() {
        ForEach(this.detailImages, item => {
          Image(item)
            .height('400lpx')
            .width('100%')
        })
      }
      .index(0)
      .autoPlay(true)
      .interval(3000)
      .indicator(true)
      .loop(true)
      .height('440lpx')
      .width('100%')
3.2 自定义弹框

1)通过**@CustomDialog**装饰器来创建自定义弹窗,使用方式可参考 自定义弹窗

2)规则弹窗效果如下,弹窗组成由两个Text和两个Button竖向排列组成;

所有我们可以在build()下使用Flex容器来包裹,组件代码如下:

@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController
  cancel: () => void
  confirm: () => void
  ShoppingCartsGoods: any[]

  build() {
    Flex() {
      Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
        Text('加入购物车成功')
          .fontColor("#000000")
          .fontSize('40lpx')
          .margin({ top: '20lpx', bottom: "20lpx" })

        Flex({ justifyContent: FlexAlign.SpaceAround }) {
          Button('取消')
            .onClick(() => {
              this.controller.close()
              this.cancel()
            }).backgroundColor(0xffffff).fontColor(Color.Black)
          Button('确定')
            .onClick(() => {
              this.controller.close()
              this.confirm()
            }).backgroundColor(0xffffff).fontColor(Color.Red)
        }.margin({ bottom: "20lpx" })
      }
    }
    .height('200lpx')
  }
}

3)在@entry创建CustomDialogController对象并传入弹窗所需参数,后面可通过该对象open()和close()方法进行打开和关闭弹窗;

dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: this.onCancel,
      confirm: this.onAccept,
      ShoppingCartsGoods: this.ShoppingCartsGoods
    }),
    cancel: this.existApp,
    autoCancel: true
  })
  onCancel() {
    CommonLog.info('Callback when the first button is clicked')
  }

  onAccept() {
    CommonLog.info('Callback when the second button is clicked')
    router.push({
      uri: "pages/HomePage",
      params: { dataList: this.ShoppingCartsGoods }
    })
  }

  existApp() {
    CommonLog.info('Click the callback in the blank area')
  }
4. 添加分布式流转

分布式流转需要在同一网络下通过 DeviceManager组件 进行设备间发现和认证,获取到可信设备的deviceId调用 featureAbility.startAbility ,即可把应用程序流转到另一设备。

1)创建DeviceManager实例;

2)调用实例的startDeviceDiscovery(),开始设备发现未信任设备;

3)设置设备状态监听on('deviceFound',callback),获取到未信任设备,并用discoverList变量进行维护;

4)传入未信任设备参数,调用实例authenticateDevice方法,对设备进行PIN码认证;

5)若是已信任设备,可通过实例的getTrustedDeviceListSync()方法来获取设备信息;

6)将设备信息中的deviceId传入featureAbility.startAbility方法,实现流转;

7)流转接收方可通过featureAbility.getWant()获取到发送方携带的数据;

项目中将上面设备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList设备信息列表,实现分布式流转只需要在deviceList中获取deviceId,然后调用featureAbility.startAbility并携带数据,即可实现分布式流转。

RemoteDeviceManager

5.分布式数据管理

分布式数据管理要求两个或多个设备在同一网络,才能监听到数据库的改变,从而渲染页面;开发步骤:

1)创建一个KVManager对象实例,用于管理数据库对象;

2)通过指定Options和storeId,创建并获取KVStore数据库,如下是参数说明;需要先通过createKVManager构建一个KVManager实例;

参数名类型必填说明
storeIdstring数据库唯一标识符,长度不大于MAX_STORE_ID_LENGTH
optionsOptions创建KVStore实例的配置信息。

3)KVStore数据库实例, KVStore.put提供增加数据的方法,如下是参数说明;

参数名类型必填说明
keystring要添加数据的key,不能为空且长度不大于MAX_KEY_LENGTH
valueUint8Array | string | number | boolean要添加数据的value,支持Uint8Array、number 、 string 、boolean,Uint8Array、string 的长度不大于MAX_VALUE_LENGTH
callbackAsyncCallback回调函数。

4) KVStore数据库实例,KVStore.on订阅指定类型的数据变更通知;一般监听远端设备变化,再进行相应操作达到分布式数据共享的效果;

本d项目通过storeId 值不同,创建了两个数据库,分别是ShoppingCartsInfo类和TotalData类,ShoppingCartsInfo应用添加商品到购物车,TotalData应用在购物车列表进行勾选结算;如下是TotalData类流程

RemoteDeviceManager

如下是ShoppingCartsInfo类流程

RemoteDeviceManager

最后,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(Harmony NEXT)资料用来跟着学习是非常有必要的。 

为了能够帮助大家快速掌握鸿蒙(Harmony NEXT)应用开发技术知识。在此给大家分享一下我结合鸿蒙最新资料整理出来的鸿蒙南北向开发学习路线以及整理的最新版鸿蒙学习文档资料。

这份鸿蒙(Harmony NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

 获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(Harmony NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

 有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

  • 26
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HarmonyOS华为公司推出的一款全场景分布式操作系统。分布式是指将多个计算设备、传感器和终端设备连接起来,通过协同工作实现更高效、便捷和智能的功能。HarmonyOS通过分布式能力整合了华为的多种设备和服务,可以在不同硬件设备之间实现互联互通,提供统一的用户体验。 首先,HarmonyOS具备分布式架构,可以将不同设备连接起来无缝协同工作。用户只需通过一台设备,就可管理和操作其他设备,实现多屏互动和内容共享。例如,用户可通过智能手机控制家中的电视、空调和摄像头等设备,实现智能家居的便捷控制。 其次,HarmonyOS拥有分布式数据管理能力。不同设备产生的数据可以在云端进行存储、分析和加工,并通过智能算法实现数据的共享和优化。例如,智能手表可以同步用户的运动数据到云端,再通过智能手机或电视展示和分析运动成果。 再者,HarmonyOS还具备分布式安全和隐私保护能力。在设备之间进行数据传输时,HarmonyOS采用了多重加密和认证技术,确保数据的安全性和完整性。同时,用户的隐私也得到充分尊重和保护,不会因为设备的连接而泄露个人信息。 最后,HarmonyOS提供了开放的分布式开发工具,使开发者能够更方便地开发分布式应用开发者可以利用HarmonyOS提供的API和框架,快速构建出支持不同设备之间的数据交互和功能共享的应用程序。 总之,HarmonyOS分布式能力的出现,使得不同设备之间的有机连接成为可能,为用户带来更多便利和智能化体验。同时,分布式也为开发者提供了更广阔的应用开发空间,推动了数字智能化的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值