当前位置: 首页 > news >正文

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().urlthis.player.on('dataLoad', () => {CommonLog.info('dataLoad duration=' + this.player.duration)this.totalTimeMs = this.player.durationif (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 = true
private controller: CustomDialogController
@Consume deviceList: RemoteDevice[]
private confirm: () => void
private 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 条目所构成。具体代码如下:

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")}

上面代码中的 GoodsList() 为每个 list 条目对应显示的信息,会便利集合中的数据,然后显示在对用的 item 布局中,具体代码如下:

@Component
struct 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 布局代码。具体代码如下:

@Component
struct 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 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

相关文章:

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

本章是 OpenHarmony 标准设备应用开发的第二篇文章。我们通过知识体系新开发的几个基于 OpenHarmony3.1 Beta 标准系统的样例:分布式音乐播放、传炸弹、购物车等样例,分别介绍下音乐播放、显示动画、动画转场(页面间转场)三个进阶…...

mysql字段乱序 information_schema

select COLUMN_NAME from information_schema.columns where table_namecollect_column_info and table_schema nz; 返回ASCII排列 导致 sqoop import \ --connect "jdbc:mysql://your_host/collect" \ --username your_username \ --password your_password \ --t…...

使用php和redis实现分布式锁

实现分布式锁是在分布式环境中确保资源独占性的重要手段。在这里,我将使用 PHP 和 Redis 来展示如何实现基于 Redis 的分布式锁。 首先,我们需要使用 Redis 的 SET 指令来尝试获取锁,并设置一个过期时间,确保锁不会永久存在。在 …...

大龄程序员是否要入职嵌入式python岗位?

在开始前我有一些资料,是我根据网友给的问题精心整理了一份「Python的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! 是否要做嵌入式 Python 取决于…...

STL—string类(1)

一、string类 1、为什么要学习string? C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP(面向对象…...

科技查新中化工领域查新点如何确立与提炼?案例讲解!

我国化工科技查新工作始于1985年,至今经历了30多年的发展。化工类课题包含化工、炼油、 冶金、能源、轻工、石化、环境、医药、环保和军工等, 具有物质种类繁多、制备工艺复杂等特点。因此,本文结合化工查新项目实例,总结提高化工…...

国网698.45报文解析工具

本文分享一个698.45协议的报文解析工具,此报文解析工具功能强大,可以解析多种国网数据协议。 下载链接: https://pan.baidu.com/s/1ngbBG-yL8ucRWLDflqzEnQ 提取码: y1de 主要界面如下: 本工具内置698.45数据协议, 即可调用word…...

留学资讯 | 2024英国学生签证申请需要满足哪些条件?

英国移民局于2020年9月10日发布了《移民规则变更声明: HC 707》,对学生签证制度进行了全面改革。该法案于2020年10月5日正式生效。根据此法案,新的学生签证——The Student and Child Student Routes学生和儿童学生路线,将替代原先的Tier 4学…...

Python 中的分步机器学习

1.安装 Python 和 SciPy 平台。 # Check the versions of libraries# Python version import sys print(Python: {}.format(sys.version)) # scipy import scipy print(scipy: {}.format(scipy.__version__)) # numpy import numpy print(numpy: {}.format(numpy.__version__)…...

C++错题集(持续更新ing)

Day 1 一、选择题 解析: 在数字不会溢出的前提下,对于正数和负数,有: 1)左移n位,相当于操作数乘以2的n次方; 2)右移n位,相当于操作数除以2的n次方。 解析&#xff1a…...

静态IP代理:网络世界的隐秘通道

在数字化时代,网络安全和隐私保护日益受到重视。静态IP代理作为一种网络服务,为用户提供了一个稳定且可预测的网络连接方式,同时保护了用户的在线身份。本文将从五个方面深入探讨静态IP代理的概念、优势、应用场景、技术实现以及选择时的考量…...

信号和槽的其他说明和优缺点

🐌博主主页:🐌​倔强的大蜗牛🐌​ 📚专栏分类:QT❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、信号与槽的断开 二、使用Lambda 表达式定义槽函数 1、局部变量引入方式 [ ] 2、函数参数 &am…...

手工创建 kamailio database tables

有些场景可能kamdbctl create不好使,可能需要手工创建 kamailio database tables,可参考下面的命令序列: USE mysql # 删除之前创建的用户 SELECT user,host FROM user; DROP USER kamailio%; FLUSH PRIVILEGES; # 删除之前创建的数据库 DROP…...

SpringBoot接收参数的19种方式

https://juejin.cn/post/7343243744479625267?share_token6D3AD82C-0404-47A7-949C-CA71F9BC9583...

Disk Map for Mac,让您的Mac更“轻”松

还在为Mac磁盘空间不足而烦恼吗?Disk Map for Mac来帮您轻松解决!通过独特的TreeMap视觉显示技术,让您一眼就能看出哪些文件和文件夹占用了大量空间。只需简单几步操作,即可快速释放磁盘空间,让您的Mac更“轻”松。快来…...

【二叉树】(三)二叉树的基础修改构造及属性求解2

(二)二叉树的基础修改构造及属性求解2 二叉树的所有路径思路递归法迭代法 左叶子之和递归法迭代法 找树左下角的值递归法迭代法 路径总和从中序与后序遍历序列构造二叉树最大二叉树合并二叉树 二叉树的所有路径 力扣原题链接:257. 二叉树的所…...

PyCharm2024安装教程

PyCharm是一款功能强大的Python集成开发环境(IDE),它提供了许多工具和功能来帮助开发者编写、调试和测试Python代码。以下是使用PyCharm的基本步骤: 安装PyCharm:首先,你需要从JetBrains官方网站下载并安装…...

JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析

🔥 个人主页:空白诗 文章目录 ⭐️ 引言🎯 变量提升(Hoisting)👻 暂时性死区(Temporal Dead Zone, TDZ)解释📦 var声明🔒 let与const声明📖 函数声明 与 函数表达式函数声…...

[Cesium]Cesium基础学习——Primitive

Cesium开发高级篇 | 01空间数据可视化之Primitive - 知乎 Primitive由两部分组成:几何体(Geometry)和外观(Appearance)。几何体定义了几何类型、位置和颜色,例如三角形、多边形、折线、点、标签等&#xff…...

java相等忽略音调

来自百度,亲测可用 java相等忽略音调 在Java中,如果你想比较两个字符串而忽略它们的音调符号,你可以使用java.text.Collator类来进行区域敏感的字符串比较。Collator类提供了根据特定区域的规则进行字符串比较的能力,可以设置忽略音调的选项…...

自养号测评实战指南:Shopee、Lazada销量翻倍不再是难题

对于速卖通、亚马逊、eBay、敦煌网、SHEIN、Lazada、虾皮等平台的卖家而言,提高店铺流量并转化为实际销量是共同追求的目标。在这个过程中,自养号进行产品测评显得尤为重要。通过精心策划和执行的测评活动,卖家不仅能够显著增加产品的销量&am…...

【Java开发面试系列】JVM相关面试题(精选)

【Java开发面试系列】JVM相关面试题(精选) 文章目录 【Java开发面试系列】JVM相关面试题(精选)前言一、JVM组成二、类加载器三、垃圾回收四、JVM实践(调优) 🌈你好呀!我是 山顶风景独…...

解决Win11下SVN状态图标显示不出来

我们正常SVN在Windows资源管理器都是有显示状态图标的, 如果不显示状态图标,可能你的注册表的配置被顶下去了,我们查看一下注册表 运行CMD > regedit 打开注册表编辑器 然后打开这个路径:计算机\HKEY_LOCAL_MACHINE\SOFTWARE…...

代码随想录训练营第四十天 | 343. 整数拆分、96.不同的二叉搜索树

343. 整数拆分 题目链接:. - 力扣(LeetCode) 文档讲解:代码随想录 视频讲解:动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分_哔哩哔哩_bilibili 状态:未通…...

python爬取数据并将数据写入execl表中

文章目录 概要 概要 提示:python爬取数据并将数据写入execl表中,仅供学习使用,代码是很久前的,可能执行不通,自行参考学习。 # -*- coding: utf-8 -*- import datetime # 日期库 import requests # 进行网络请求 im…...

Linux动静态库

Linux动静态库 1.动静态库介绍 在程序翻译的链接阶段,其实就是把一堆.o文件链接在一起形成.exe文件。如果一个程序中需要链接很多个.o文件,那么这些.o文件就需要被打包才方便管理,**库文件本质就是把.o文件打包。**库文件是一种提高开发效率…...

线程与进程___(一)

1、线程 Thread 类创建得线程为前台线程,线程池中的为后台线程,,,Main方法结束后,前台线程仍然运行,直到完成,而后台线程立刻结束。 调用线程时候不会立刻进入 Running 状态, 而是…...

Google IO 2024有哪些看点呢?

有了 24 小时前 OpenAI 用 GPT-4o 带来的炸场之后,今年的 Google I/O 还未开始,似乎就被架在了一个相当尴尬的地位,即使每个人都知道 Google 将发布足够多的新 AI 内容,但有了 GPT-4o 的珠玉在前,即使是 Google 也不得…...

纯血鸿蒙APP实战开发——Navigation页面跳转对象传递案例

介绍 本示例主要介绍在使用Navigation实现页面跳转时,如何在跳转页面得到转入页面传的类对象的方法。实现过程中使用了第三方插件class-transformer,传递对象经过该插件的plainToClass方法转换后可以直接调用对象的方法, 效果图预览 使用说…...

Windows C++ 读取、修改配置文件.ini

目录 一、INI文件基础介绍 二、GetPrivateProfileString和WritePrivateProfileString 解释: 一、INI文件基础介绍 INI文件(初始化文件)是一种简单的文本文件,用于存储程序的配置设置。它们通常用于Windows操作系统环境中&#x…...