0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在OpenHarmony中实现音乐播放、显示动画、动画转场

电子发烧友开源社区 来源:HarmonyOS官方合作社区 作者:HarmonyOS官方合作社 2022-02-25 11:37 次阅读

上一章我们讲解了应用编译环境准备,设备编译环境准备,开发板烧录,将一个最简单的 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 = null
build() {   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官方合作社区】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 显示
    +关注

    关注

    0

    文章

    408

    浏览量

    44924
  • 播放
    +关注

    关注

    0

    文章

    13

    浏览量

    13533
  • OpenHarmony
    +关注

    关注

    23

    文章

    3259

    浏览量

    15159

原文标题:OpenHarmony标准设备应用开发(二)——布局、动画与音乐

文章出处:【微信号:HarmonyOS_Community,微信公众号:电子发烧友开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    LabVIEW动画实现的一种新方法

    、尺寸、颜色等属性来达到动画效果。c、利用Pict Ring控件实现图片播放器的功能。Pict Ring控件可保存一图片序列,而只显示当前图片。合理设置一循环结构,可方便地完成多帧图片
    发表于 01-08 11:30

    怎么去解决QLabel控件无法播放GIF动画的问题

    ubuntu系统上gif动画播放正常,移植到arm上的应用程序是正常启动的,但QLabel控件上无法播放GIF动画。QLabel控件上图片是可以正常
    发表于 01-10 07:40

    请问一下如何在uboot中进行RK开机动画播放

    请问一下如何在uboot中进行RK开机动画播放呢?
    发表于 03-04 07:47

    OpenHarmony标准设备应用开发笔记汇总

    (以下简称“OpenHarmony”),相关控件在布局如何使用,以及在 OpenHarmony 如何
    发表于 03-28 14:19

    OpenHarmony标准设备应用开发(二)——布局、动画音乐

    3.1 Beta 标准系统的样例:分布式音乐播放、传***、购物车等样例,分别介绍下音乐播放显示动画
    发表于 04-07 17:09

    每日推荐 | STM32超低功耗资料及OpenHarmony标准设备应用开发

    (页面间转场)三个进阶技能。首先我们来讲如何在 OpenHarmony 实现音乐
    发表于 04-08 10:16

    HarmonyOS应用开发-ACE 2.0转场动画体验

    一、组件说明展现了ACE 2.0转场动画的使用。其中包含页面间转场、组件内转场以及共享元素转场。二、效果图三、完整代码地址https://g
    发表于 08-23 10:30

    何在stm32mp1上添加对动画动画面的支持呢?

    大家好,如何在 stm32mp1 上添加对动画动画面的支持?我了解用于自定义引导屏幕的 psplash 配方,它工作得很好。我想在系统启动时播放
    发表于 12-16 06:07

    HarmonyOS/OpenHarmony应用开发-属性动画

    组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate
    发表于 01-03 10:51

    HarmonyOS/OpenHarmony应用开发-显示动画

    : AnimateParam, event: ()=> void) : void描述:提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。event指定显示动效的闭包函数
    发表于 01-05 10:42

    动画激光灯的特点_动画激光灯应用

    动画激光灯是一种能跟随播放音乐节奏能打出各种文字和图案的设备。它不仅内设红黄绿三种颜色的激光动画来搭配舞台效果而且还能实现旋转、缩放、频闪
    发表于 04-09 17:25 1509次阅读

    如何通过分布式数据管理实现多台设备间的数据同步更新

    OpenHarmony 中如何实现音乐播放显示动画
    的头像 发表于 02-25 11:47 3097次阅读
    如何通过分布式数据管理<b class='flag-5'>实现</b>多台设备间的数据同步更新

    openharmony第三方组件适配移植的动画实现

    项目介绍 项目名称:CanAnimation 所属系列:openharmony的第三方组件适配移植 功能:使用openharmony属性动画写的一个库,可组建动画队列,可
    发表于 04-02 11:30 3次下载

    OpenHarmony技术论坛:传统动画实现的不足

    OpenHarmony技术论坛:流畅动画可传统动画实现的不足。
    的头像 发表于 04-25 14:21 795次阅读
    <b class='flag-5'>OpenHarmony</b>技术论坛:传统<b class='flag-5'>动画</b><b class='flag-5'>实现</b>的不足

    何在OpenHarmony实现逐帧动画

    逐帧动画是常见的一种动画呈现形式,本例就为大家介绍如何通过 translate(),setInterval(),clearAllInterval() 等方法实现逐帧动画
    的头像 发表于 06-18 15:14 500次阅读
    如<b class='flag-5'>何在</b><b class='flag-5'>OpenHarmony</b>上<b class='flag-5'>实现</b>逐帧<b class='flag-5'>动画</b>?