赞
踩
分布式购物车demo 模拟的是我们购物时参加满减活动,进行拼单的场景;实现两人拼单时,其他一人添加商品到购物车,另外一人购物车列表能同步更新,且在购物车列表页面结算时,某一人结算对方也能实时知道结算金额和优惠金额。整个操作效果分为3个小动画,
完整的项目结构目录如下
├─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
在DevEco Studio中点击File -> New Project ->[Standard]Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。
效果图如上可以分为两部分
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) }
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() } }
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%')
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') }
分布式流转需要在同一网络下通过 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并携带数据,即可实现分布式流转。
分布式数据管理
要求两个或多个设备在同一网络,才能监听到数据库的改变,从而渲染页面;开发步骤:
1)创建一个KVManager对象实例,用于管理数据库对象;
2)通过指定Options和storeId,创建并获取KVStore数据库,如下是参数说明;需要先通过createKVManager构建一个KVManager实例;
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
storeId | string | 是 | 数据库唯一标识符,长度不大于 MAX_STORE_ID_LENGTH。 |
options | Options | 是 | 创建KVStore实例的配置信息。 |
3)KVStore数据库实例, KVStore.put提供增加数据的方法,如下是参数说明;
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
key | string | 是 | 要添加数据的key,不能为空且长度不大于 MAX_KEY_LENGTH 。 |
value | Uint8Array | string | number |
callback | AsyncCallback | 是 | 回调函数。 |
4) KVStore数据库实例,KVStore.on订阅指定类型的数据变更通知;一般监听远端设备变化,再进行相应操作达到分布式数据共享的效果;
本d项目通过storeId 值不同,创建了两个数据库,分别是ShoppingCartsInfo类和TotalData类,ShoppingCartsInfo应用添加商品到购物车,TotalData应用在购物车列表进行勾选结算;如下是TotalData类流程
如下是ShoppingCartsInfo类流程
1)git下载
git clone https://gitee.com/openharmony-sig/knowledge_demo_shopping.git --depth=1
2)项目导入
打开DevEco Studio,点击File->Open->下载路径/FA/Shopping/DistributedShoppingCart
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。