HarmonyOS鸿蒙Next线上Codelabs系列挑战赛:海滩拾贝

HarmonyOS鸿蒙Next线上Codelabs系列挑战赛:海滩拾贝

HarmonyOS线上Codelabs系列挑战赛第三期:海滩拾贝

1 前言

因为时间原因没能参加前面两期Codelabs挑战赛,所以这就是我的第一个Codelabs作品啦。整整用了大概一天时间,费了我不少心血,不管代码质量如何,也算非常幸运地实现了我理想中的大部分效果。

这个demo类似于一个小游戏,背景是一块小小的海滩,上面会一些贝壳、海螺、海星,你可以将这些物件收集起来,收集物件时会附带一张写有文字的小卡片,之后你也打开查看你收集到的所有物件。在demo中,我将属性动画和显式动画融入到收集物件、和查看物件的过程中,总的来说呈现的视觉效果我挺满意的,这都多亏HarmonyOS提供的强大的API能力,让我这个对动画没有什么了解的小白也能快速地实现一些简单的动画效果。

demo效果展示


2 项目搭建

2.1 开发环境要求

  • IDE:DevEco Studio 3.1 Canary1
  • HarmonyOS SDK: API 9

2.2 创建项目

  1. 选择Ability模板:选择HarmonyOS,Empty Ability。

  2. 填写项目信息:输入项目名称,默认选择SDK版本为API 9,默认选择Model为Stage。点击Finish即完成创建。


3 开发过程

3.1 定义数据结构

在common/model目录下新建ItemModel.ets文件。

export class ItemModel {
  image: Resource; //图片
  name: string; //名称
  content: string //文字内容

  constructor(image: Resource, name: string, content: string) {
    this.image = image;
    this.name = name;
    this.content = content;
  }

  static getData(): ItemModel[] {
    return modelData;
  }
}

let modelData = [...];

3.2 定义物件组件

在common/views目录下新建Item.ets文件。每个Item组件各自拥有一个ItemModel,组件会将ItemModel中的图片(比如说一个海螺)显示出来,itemVisibility和itemOpacity分别控制组件的可见性和不透明度。点击图片后,会先触发onItemClick()函数(这个函数在初始化组件的时候传入,后面会提到),再使用animateTo播放显式动画,设置海螺不透明度为0,这样就能实现组件在屏幕上逐渐消失的效果,同时在动画播放完成后,将海螺的可见性设置为不可见。另外,这里还用到了transform属性,其作用是根据传入的矩阵对UI元素进行矩阵变换,这里我实现的效果是将物件绕z轴(即垂直于屏幕的坐标轴)旋转一个随机的角度,这样每次实例化出来的海螺的摆放角度就会不一样。关于矩阵变换的用法,可以查看官方文档

3.3 定义物件卡片

在common/views目录下新建Card.ets文件。这个组件的重点是实现打开时由小变大,逐渐可见的同时加上旋转180°,关闭时由大变小、逐渐消失、向右上角平移的效果。你可以能疑惑为什么打开时不是旋转360°,因为事实是如果指定旋转角度为360°,就不会触发旋转动画效果了,具体原因我也不知道。不过我后来发现可以不用矩阵变换的方式,而是用rotate属性来触发动画,这样就能转360°(甚至更多)了,但是旋转180°和360°的效果也相差不大,能不改就不改吧:) 。

要实现这些效果,需要提取出组件宽高、不透明度和用于变换的矩阵这几个属性,并用@State装饰器修饰。在外部点击物件时,触发卡片的显现动画,当点击卡片中的关闭按钮或“收下宝贝”按钮时,触发卡片的消失动画,这里我使用的都是显式动画。

item变量需要与入口组件绑定,让卡片能显示你所点击的物件对应的内容。showCard变量用于控制卡片的可见性,并用了@Watch装饰器来监听变量的变化,实现当卡片被设置为可见时,播放显现的动画。collections变量由入口组件提供,用来存储已收集的物件。

3.3 定义物件收集列表

在common/views目录下新建CollectionsList.ets文件。CollectionsList组件主要用于将收集的物件以列表形式展示出来,但重点在于CollectionListItem组件(下面统称收集项)。

收集项中用属性动画实现了点击放大并旋转图片,恢复时缩放回原始大小的效果。收集项组件中用flag变量记录组件的状态,根据该状态为属性设置不同的值来触发属性动画。这里的旋转效果是通过rotate属性来实现的,先定义一个@State RotateOptions类型的变量并初始化旋转角度为0,触发动画时再设置该变量,指定绕y轴旋转360°。

3.5 定义收集器组件

在common/views目录下新建ItemsCollector.ets文件。这个组件其实就是组合了一个关闭的按钮和刚才定义的收集列表,也用了卡片式的外观。这里我用属性动画实现打开时逐渐显现的效果,用属性动画实现关闭时逐渐消失、缩小、向右上角平移的效果,实现的方法和上面的物件组件差不多。

3.6 入口组件

到这里,只需要把前面定义好的组件组合到一起就差不多完成了。这里我用Stack容器作为最外层布局,用来放置一张沙滩的背景图片。内部用了Column容器,先放置一个玻璃瓶的图片作为收集器的开启按钮,在使用ForEach循环渲染出所有的物件,在物件的onItemClick属性中定义一个箭头函数,点击物件时设置卡片的内容并将卡片显示。在Stack容器上层分别放置收集器页面和卡片页面,初始都为不可见状态。为了给物件出现的位置赋予一些随机性,我采用的方法是为每一个物件产生随机的Margin(即外边距),这样每次刷新后,每一个物件的位置在屏幕的一定范围内分布都是比较随机的。


4 总结

无论是使用显式动画还是使用属性动画,最后都能达到相同的效果,只不过在不同场景下,有可能用属性动画比较方便,也可能用显式动画比较方便,具体还得看个人喜好。


更多关于HarmonyOS鸿蒙Next线上Codelabs系列挑战赛:海滩拾贝的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next线上Codelabs系列挑战赛:海滩拾贝的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS鸿蒙Next线上Codelabs系列挑战赛中的“海滩拾贝”活动,旨在通过实践项目帮助开发者深入理解鸿蒙系统的开发流程和技术要点。参与者将利用鸿蒙的分布式能力、ArkUI框架等核心技术,完成一个与海滩拾贝相关的应用开发。挑战赛不仅提供了详细的学习资源和代码示例,还鼓励开发者创新,提升实际开发能力。通过参与,开发者可以快速掌握鸿蒙系统的开发技巧,为未来的项目积累宝贵经验。

回到顶部