上一章我们讲解了应用编译环境准备,设备编译环境准备,开发板烧录,将一个最简单的 openatom openharmony(以下简称“openharmony”)程序安装到我们的标准设备上。
本章是 openharmony 标准设备应用开发的第二篇文章。我们通过知识体系新开发的几个基于 openharmony3.1 beta 标准系统的样例:分布式音乐播放、传炸弹、购物车等样例,分别介绍下音乐播放、显示动画、动画转场(页面间转场)三个进阶技能。首先我们来讲如何在 openharmony 中实现音乐的播放。
分布式音乐播放
通过分布式音乐播放器,大家可以学到一些 arkui 组件和布局在 openharmony 中是如何使用的,以及如何在自己的应用中实现音乐的播放,暂停等相关功能。应用效果如下图所示:
1.1界面布局
首先是页面整体布局,部分控件是以模块的方式放在整体布局中的,如 operationpannel()、sliderpannel()、playpannel() 模块。页面整体布是由 flex 控件中,包含 image、text 以及刚才所说的三个模块所构成。
build() { flex({ direction: flexdirection.column, alignitems: itemalign.center, justifycontent: flexalign.spacebetween }) { flex({ direction: flexdirection.column, alignitems: itemalign.center }) { flex({ direction: flexdirection.row, justifycontent: flexalign.end }) { image($r(app.media.icon_liuzhuan)).width(32).height(32) }.padding({ right: 32 }).onclick(() => { this.ondistributedevice() }) flex({ direction: flexdirection.row, justifycontent: flexalign.center }) { image($r(app.media.bg_classic)).width(312).height(312) }.margin({ top: 24 }) text(this.currentmusic.name).fontsize(20).fontcolor(#e6000000).margin({ top: 10 }) text(未知音乐家).fontsize(14).fontcolor(#99000000).margin({ top: 10 }) }.flexgrow(1) flex({ direction: flexdirection.column, alignitems: itemalign.center, justifycontent: flexalign.end }) { this.operationpannel() this.sliderpannel() this.playpannel() }.height(200) } .lineargradient({ angle: 0, direction: gradientdirection.bottom, colors: this.currentmusic.backgourdcolor }).padding({ top: 48, bottom: 24, left: 24, right: 24 }) .width('100%') .height('100%') }
operationpannel() 模块的布局,该部分代码对应图片中的心形图标,下载图标,评论图标更多图标这一部分布局。其主要是在 flex 中包含 image 所构成代码如下:
@builder operationpannel() { flex({ direction: flexdirection.row, alignitems: itemalign.center, justifycontent: flexalign.spacebetween }) { image($r(app.media.icon_music_like)).width(24).height(24) image($r(app.media.icon_music_download)).width(24).height(24) image($r(app.media.icon_music_comment)).width(24).height(24) image($r(app.media.icon_music_more)).width(24).height(24) }.width('100%').height(49).padding({ bottom: 25 }) }
sliderpannel() 模块代码布局。该部分对应图片中的显示播放时间那一栏的控件。整体构成是在 flex 中,包含 text、slider、text 三个控件。具体代码如下:
@builder sliderpannel() { flex({ direction: flexdirection.row, alignitems: itemalign.center, justifycontent: flexalign.center }) { text(this.currenttimetext).fontsize(12).fontcolor(ff000000).width(40) slider({ value: this.currentprogress, min: 0, max: 100, step: 1, style: sliderstyle.inset }) .blockcolor(color.white) .trackcolor(color.gray) .selectedcolor(color.blue) .showsteps(true) .flexgrow(1) .margin({ left: 5, right: 5 }) .onchange((value: number, mode: sliderchangemode) => { if (mode == 2) { commonlog.info('aaaaaaaaaaaaaa1: ' + this.currentprogress) this.onchangemusicprogress(value, mode) } }) text(this.totaltimetext).fontsize(12).fontcolor(ff000000).width(40) }.width('100%').height(18) }
playpannel() 模块代码对应图片中的最底部播放那一栏五个图标所包含的一栏。整体布局是 flex 方向为横向,其中包含五个 image 所构成。具体代码如下:
@builder playpannel() { flex({ direction: flexdirection.row, alignitems: itemalign.center, justifycontent: flexalign.spacebetween }) { image($r(app.media.icon_music_changemode)).width(24).height(24).onclick(() => { this.onchangeplaymode() }) image($r(app.media.icon_music_left)).width(32).height(32).onclick(() => { this.onpreviousmusic() }) image(this.isplaying ? $r(app.media.icon_music_play) : $r(app.media.icon_music_stop)) .width(80) .height(82) .onclick(() => { this.onplayorpausemusic() }) image($r(app.media.icon_music_right)).width(32).height(32).onclick(() => { this.onnextmusic() }) image($r(app.media.icon_music_list)).width(24).height(24).onclick(() => { this.onshowmusiclist() }) }.width('100%').height(82) }
希望通过上面这些布局的演示,可以让大家学到一些部分控件在 openharmony 中的运用,这里使用的 arkui 布局和 harmonyos* 是一致的,目前 harmonyos* 手机还没有发布 arkui 的版本,大家可以在 openharmony 上抢先体验。常用的布局和控件还有很多,大家可以在下面的链接中找到更多的详细信息。
*编者注:harmonyos 是基于开放原子开源基金会旗下开源项目 openharmony 开发的面向多种全场景智能设备的商用版本。是结合其自有特性和能力开发的新一代智能终端操作系统。
1.2 播放音乐
play(seekto) { if (this.player.state == 'playing' && this.player.src == this.getcurrentmusic().url) { return } if (this.player.state == 'idle' || this.player.src != this.getcurrentmusic().url) { commonlog.info('preload music url = ' + this.getcurrentmusic().url) this.player.reset() this.player.src = this.getcurrentmusic().url this.player.on('dataload', () => { commonlog.info('dataload duration=' + this.player.duration) this.totaltimems = this.player.duration if (seekto > this.player.duration) { seekto = -1 } this.player.on('play', (err, action) => { if (err) { commonlog.info(`musicplayer[playermodel] error returned in play() callback`) return } if (seekto > 0) { this.player.seek(seekto) } }) this.player.play() this.statuschangelistener() this.setprogresstimer() this.isplaying = true }) } else { if (seekto > this.player.duration) { seekto = -1 } this.player.on('play', (err, action) => { if (err) { commonlog.info(`musicplayer[playermodel] error returned in play() callback`) return } if (seekto > 0) { this.player.seek(seekto) } }) this.player.play() this.setprogresstimer() this.isplaying = true } }
1.3 音乐暂停
pause() { commonlog.info(pause music) this.player.pause(); this.cancelprogresstimer() this.isplaying = false }
接下来我们讲解如何在 openharmony 中实现显示动画的效果。
显示动画
我们以传炸弹小游戏中的显示动画效果为例,效果如下图所示。
通过本小节,大家在上一小节的基础上,学到更多 arkui 组件和布局在 openharmony 中的应用,以及如何在自己的应用中实现显示动画的效果。
实现步骤:
2.1编写弹窗布局:将游戏失败文本、炸弹图片和再来一局按钮图片放置于column容器中;
2.2用变量来控制动画起始和结束的位置:用flex容器包裹炸弹图片,并用 @state 装饰变量 toggle,通过变量来动态修改 flex 的 direction 属性;布局代码如下:
@state toggle: boolean = trueprivate controller: customdialogcontroller@consume devicelist: remotedevice[]private confirm: () => voidprivate interval = nullbuild() { column() { text('游戏失败').fontsize(30).margin(20) flex({ direction: this.toggle ? flexdirection.column : flexdirection.columnreverse, alignitems: itemalign.center }) { image($r(app.media.bomb)).objectfit(imagefit.contain).height(80) }.height(200) image($r(app.media.btn_restart)).objectfit(imagefit.contain).height(120).margin(10) .onclick(() => { this.controller.close() this.confirm() }) } .width('80%') .margin(50) .backgroundcolor(color.white)}
2.3设置动画效果:使用 animateto 显式动画接口炸弹位置切换时添加动画,并且设置定时器定时执行动画,动画代码如下:
abouttoappear() { this.setbombanimate()}setbombanimate() { let fun = () => { this.toggle = !this.toggle; } this.interval = setinterval(() => { animateto({ duration: 1500, curve: curve.sharp }, fun) }, 1600)} 转场动画(页面间转场)
我们同样希望在本小节中,可以让大家看到更多的 arkui 中的组件和布局在 openharmony 中的使用,如何模块化的使用布局,让自己的代码更简洁易读,以及在应用中实现页面间的转场动画效果。
整体布局由 column、scroll、flex、image 以及 goodshome()、myinfo()、homebottom() 构成,该三个模块我们会分别说明。具体代码如下:
build() { column() { scroll() { 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() } } .height('85%') } .flexgrow(1) homebottom({ remotedata: this.remotedata}) } .backgroundcolor(white) }
goodshome() 模块对应效果图中间显示商品的部分,其主要结构为 tabcontent 中包含的两个 list 条目所构成。具体代码如下:
@componentstruct goodshome { private goodsitems: goodsdata[] @consume shoppingcartsgoods :any[] build() { column() { tabs() { tabcontent() { goodslist({ goodsitems: this.goodsitems}); } .tabbar(畅销榜) .backgroundcolor(color.white) tabcontent() { goodslist({ goodsitems: this.goodsitems}); } .tabbar(推荐) .backgroundcolor(color.white) } .barwidth(500) .barheight(50) .scrollable(true) .barmode(barmode.scrollable) .height('980lpx') } .alignitems(horizontalalign.start) .width('100%') }}
上面代码中的 goodslist() 为每个 list 条目对应显示的信息,会便利集合中的数据,然后显示在对用的 item 布局中,具体代码如下:
@componentstruct goodslist { private goodsitems: goodsdata[] @consume shoppingcartsgoods :any[] build() { column() { list() { foreach(this.goodsitems, item => { listitem() { goodslistitem({ goodsitem: item}) } }, item => item.id.tostring()) } .width('100%') .align(alignment.top) .margin({ top: '10lpx' }) } }}
最后就是 list 的 item 布局代码。具体代码如下:
@componentstruct goodslistitem { private goodsitem: goodsdata @state scale: number = 1 @state opacity: number = 1 @state active: boolean = false @consume shoppingcartsgoods :any[] build() { column() { 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' }) } }
备注:myinfo() 模块对应的事其它也免得布局,这里就不做说明。
最后我们来说一下,页面间的页面间的转场动画,其主要是通过在全局 pagetransition 方法内配置页面入场组件和页面退场组件来自定义页面转场动效。具体代码如下:
// 转场动画使用系统提供的多种默认效果(平移、缩放、透明度等) pagetransition() { pagetransitionenter({ duration: 1000 }) .slide(slideeffect.left) pagetransitionexit({ duration: 1000 }) .slide(slideeffect.right) }}
通过上述讲解,我们就在自己的代码中实现音乐的播放,显示动画,页面间转场动画等效果。在接下来的一章中,我们会讲解如何在 openharmony 通过分布式数据管理,实现设备之间数据如何同步刷新。
在接下来的一章中,我们将会讲解分布式数据管理在 openharmony 中如何实现多台设备间的数据同步更新。
原文标题:openharmony标准设备应用开发(二)——布局、动画与音乐
文章出处:【微信公众号:harmonyos官方合作社区】欢迎添加关注!文章转载请注明出处。
电动汽车车载充电器中的宽带隙 (WBG) 晶体管
粮食脱粒机设备如何实现故障监控与高效运维
ios10.3怎么样?ios10.3评测:ios10.3.2beta5重磅更新,老用户既开心又伤感
战斗力瞬间爆表丨aigo国民好物固态硬盘P3000
狙击iPhone8和华为mate10,三星准备的是三星note8!
如何在OpenHarmony中实现音乐播放、显示动画、动画转场
华为将提供端云协同的AI开发及应用平台
5G手机元年? IDC 权威报告称今年5G出货量仅为全球的0.5%
变压器能效提升计划(2021-2023)工信部国家能源局市场监管局联合印发
雷军直播:红米3X性能优越 叹手机发展进入瓶颈期
你的芯片真的安全吗?
异或运算法则和异或符号在multisim和word的输入方法
iPhone 12系列又一问题被曝
5G给内存和存储带来了什么样的发展美光科技的解答
小米10的出现或将有可能撼动华为在业界的地位
Arduino的各种常用开发板
骁龙888集成全新Qualcomm Kryo 680 CPU
7nm芯片和5nm芯片哪个好
FOTA会影响到自动驾驶车辆数据安全哪些方面
喜讯!赛昉科技通过ISO9001质量管理体系认证