HarmonyOS:@AnimatableExtend 装饰器自学指南

简介: 本文详细介绍了 `@AnimatableExtend` 装饰器的使用方法与应用场景,帮助开发者实现复杂动画效果。从 API Version 10 开始支持的该装饰器,可通过自定义动画属性对不同类型数据进行处理。文章通过改变 Text 组件宽度和实现折线动画两个示例,展示了装饰器的强大功能。同时解析了 `AnimatableArithmetic<T>` 接口的加减乘除及相等判断规则,为非 number 类型数据动画提供解决方案。总结中强调了装饰器的灵活性,鼓励开发者在项目中实践,提升应用动画体验。

在最近的项目开发中,我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中,我发现了 ​​@AnimatableExtend​​​ 装饰器,它为实现动画效果提供了一种非常灵活且强大的方式。然而,在学习这个装饰器的过程中,我发现相关的资料并不是特别丰富,而且很多资料都缺乏系统性的讲解。因此,我决定写这篇博客,将自己的学习经验和理解分享出来,希望能帮助更多的开发者快速掌握 ​​@AnimatableExtend​​ 装饰器的使用。

1. ​​@AnimatableExtend​​ 装饰器概述

​@AnimatableExtend​​ 装饰器从 API Version 10 开始支持,为动画效果的实现提供了一种便捷的方式。从 API version 11 开始,它支持在元服务中使用。这个装饰器允许我们自定义动画属性,使得我们可以对不同类型的数据进行动画处理。

1.1 装饰器使用规则

  • 定义位置:​​@AnimatableExtend​​ 仅支持定义在全局,不支持在组件内部定义。
  • 参数类型:​​@AnimatableExtend​​​ 定义的函数参数类型必须为 ​​number​​​ 类型或者实现 ​​AnimatableArithmetic<T>​​ 接口的自定义类型。
  • 函数体限制:​​@AnimatableExtend​​​ 定义的函数体内只能调用 ​​@AnimatableExtend​​ 括号内组件的属性方法。

1.2 ​​AnimatableArithmetic<T>​​ 接口说明

​AnimatableArithmetic<T>​​​ 接口定义了非 ​​number​​​ 数据类型的动画运算规则。对于非 ​​number​​ 类型的数据(如数组、结构体、颜色等)做动画,需要实现该接口中的加法、减法、乘法和判断相等函数,使得该数据能参与动画的插值运算和识别该数据是否发生改变。

名称 入参类型 返回值类型 说明
plus AnimatableArithmetic AnimatableArithmetic 定义该数据类型的加法运算规则
subtract AnimatableArithmetic AnimatableArithmetic 定义该数据类型的减法运算规则
multiply number AnimatableArithmetic 定义该数据类型的乘法运算规则
equals AnimatableArithmetic boolean 定义该数据类型的相等判断规则

2. 使用场景示例

2.1 改变 Text 组件宽度实现逐帧布局效果

下面的示例通过改变 ​​Text​​ 组件的宽度实现逐帧布局的效果。

@AnimatableExtend(Text)
function animatableWidth(width: number) {
  .width(width)
}

@Entry
@Component
struct AnimatablePropertyExample {
  @State textWidth: number = 100;

  build() {
    Column() {
      Text("AnimatableProperty")
        .animatableWidth(this.textWidth)
        .animation({ duration: 3000, curve: Curve.EaseInOut })
      Button("Play")
        .onClick(() => {
          this.textWidth = this.textWidth == 100 ? 200 : 100;
        })
    }.width("100%")
    .padding(20)
  }
}
AI 代码解读

在这个示例中,我们定义了一个 ​​animatableWidth​​​ 函数,通过 ​​@AnimatableExtend​​​ 装饰器将其应用到 ​​Text​​​ 组件上。点击按钮时,​​textWidth​​ 的值会在 100 和 200 之间切换,从而触发动画效果。

2.2 实现折线的动画效果

为了实现折线的动画效果,我们需要定义一个自定义类型 ​​Point​​​ 和 ​​PointVector​​​,并让 ​​PointVector​​​ 实现 ​​AnimatableArithmetic<T>​​ 接口。

class Point {
  x: number
  y: number

  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }

  plus(rhs: Point): Point {
    return new Point(this.x + rhs.x, this.y + rhs.y)
  }

  subtract(rhs: Point): Point {
    return new Point(this.x - rhs.x, this.y - rhs.y)
  }

  multiply(scale: number): Point {
    return new Point(this.x * scale, this.y * scale)
  }

  equals(rhs: Point): boolean {
    return this.x === rhs.x && this.y === rhs.y
  }
}

// PointVector实现了AnimatableArithmetic<T>接口
class PointVector extends Array<Point> implements AnimatableArithmetic<PointVector> {
  constructor(value: Array<Point>) {
    super();
    value.forEach(p => this.push(p))
  }

  plus(rhs: PointVector): PointVector {
    let result = new PointVector([])
    const len = Math.min(this.length, rhs.length)
    for (let i = 0; i < len; i++) {
      result.push((this as Array<Point>)[i].plus((rhs as Array<Point>)[i]))
    }
    return result
  }

  subtract(rhs: PointVector): PointVector {
    let result = new PointVector([])
    const len = Math.min(this.length, rhs.length)
    for (let i = 0; i < len; i++) {
      result.push((this as Array<Point>)[i].subtract((rhs as Array<Point>)[i]))
    }
    return result
  }

  multiply(scale: number): PointVector {
    let result = new PointVector([])
    for (let i = 0; i < this.length; i++) {
      result.push((this as Array<Point>)[i].multiply(scale))
    }
    return result
  }

  equals(rhs: PointVector): boolean {
    if (this.length != rhs.length) {
      return false
    }
    for (let i = 0; i < this.length; i++) {
      if (!(this as Array<Point>)[i].equals((rhs as Array<Point>)[i])) {
        return false
      }
    }
    return true
  }

  get(): Array<Object[]> {
    let result: Array<Object[]> = []
    this.forEach(p => result.push([p.x, p.y]))
    return result
  }
}

@AnimatableExtend(Polyline)
function animatablePoints(points: PointVector) {
  .points(points.get())
}

@Entry
@Component
struct AnimatablePropertyExample {
  @State points: PointVector = new PointVector([
    new Point(30, Math.random() * 250),
    new Point(80, Math.random() * 250),
    new Point(130, Math.random() * 250),
    new Point(180, Math.random() * 250),
    new Point(230, Math.random() * 250),
  ])

  build() {
    Column() {
      Polyline()
        .animatablePoints(this.points)
        .animation({ duration: 1500, curve: Curve.EaseOut })// 设置动画参数
        .size({ height: 250, width: 350 })
        .fill(Color.Blue)
        .stroke(Color.Yellow)
        .backgroundColor('#aaccff')
      Button("Play")
        .onClick(() => {
          // points是实现了可动画协议的数据类型,points在动画过程中可按照定义的运算规则、动画参数从之前的PointVector变为新的PointVector数据,产生每一帧的PointVector数据,进而产生动画
          this.points = new PointVector([
            new Point(30, Math.random() * 250),
            new Point(80, Math.random() * 250),
            new Point(130, Math.random() * 250),
            new Point(180, Math.random() * 250),
            new Point(230, Math.random() * 250),
          ])
        })
    }.width("100%")
    .padding(20)
  }
}
AI 代码解读

123132025-03-23 22-09-32.2025-03-23 22_09_55.gif

在这个示例中,我们定义了 ​​Point​​​ 类表示二维平面上的点,​​PointVector​​​ 类表示点的数组。通过实现 ​​AnimatableArithmetic<T>​​​ 接口,我们为 ​​PointVector​​​ 定义了加法、减法、乘法和相等判断规则。然后,我们使用 ​​@AnimatableExtend​​​ 装饰器将 ​​animatablePoints​​​ 函数应用到 ​​Polyline​​ 组件上,点击按钮时,折线的顶点位置会随机变化,从而实现动画效果。

3. 总结

​@AnimatableExtend​​​ 装饰器为实现复杂动画效果提供了一种强大而灵活的方式。通过自定义动画属性和实现 ​​AnimatableArithmetic<T>​​​ 接口,我们可以对不同类型的数据进行动画处理。在实际开发中,我们可以根据具体需求灵活运用这个装饰器,实现各种炫酷的动画效果。希望这篇博客能帮助你快速掌握 ​​@AnimatableExtend​​ 装饰器的使用,让你的应用更加生动有趣。

通过以上的学习和实践,你可以逐步掌握 ​​@AnimatableExtend​​ 装饰器的使用方法,并且在实际项目中灵活运用,为用户带来更加丰富的动画体验。

目录
相关文章
HarmonyOS:ArkTS RowSplit 组件自学指南
在 ArkTS 开发中,复杂界面布局需求常见,尤其需要灵活调整子组件宽度时,传统方式难以满足动态交互需求。`RowSplit` 组件解决了这一问题,支持横向布局并插入可拖动的分割线,让用户轻松调整子组件宽度,提升体验。本文详细介绍了 `RowSplit` 的功能、接口、属性及使用示例,帮助开发者掌握其用法,并总结了注意事项。通过合理配置,可实现灵活美观的布局效果。希望对您有帮助,欢迎关注、点赞和收藏!
69 31
|
23天前
|
HarmonyOS:ArkTS 多态样式自学指南
本文介绍了 ArkTS 多态样式功能,帮助开发者为组件设置不同状态(如点击、按下、禁用等)下的样式。从 API Version 8 开始支持,API Version 11 引入 `attributeModifier` 动态设置属性。核心接口 `stateStyles` 支持多种状态,如 `normal`、`pressed`、`disabled` 等。文章通过示例代码展示了如何为 `Text` 和 `Radio` 组件设置多态样式,结合状态控制实现动态视觉反馈。掌握此功能可提升用户体验,推荐开发者根据需求灵活运用。
66 27
|
23天前
|
HarmonyOS:ArkTS Path 组件自学指南
在鸿蒙应用开发中,绘制复杂图形常面临传统布局方式难以满足需求的问题。ArkTS 的 Path 组件提供了解决方案,如同一把“神奇画笔”,支持通过灵活的命令和属性绘制直线、曲线、椭圆弧等多样图形。本文详细介绍了 Path 组件从 API Version 7 起的功能特性,包括 `commands`、`fill`、`stroke` 等核心属性,以及各类绘图命令如 `M`(移动)、`L`(直线)、`C`(贝塞尔曲线)等。结合示例代码,展示了如何绘制简单直线到复杂曲线图形,并拓展了颜色、透明度和线条样式的自定义方法。掌握 Path 组件,可为应用带来更丰富生动的视觉体验,助力开发者实现创意绘图需求。
64 21
|
22天前
|
HarmonyOS NEXT - 样式装饰器:@Styles和@Extend
简介:本文介绍了用于提升代码简洁性和样式复用性的装饰器@Styles和@Extend。@Styles可将多条样式提取为方法,在组件声明处调用,支持静态样式复用;其缺点是仅支持通用属性与事件,且不支持参数。@Extend用于扩展原生组件样式,支持封装私有属性、事件及全局方法,允许传参(包括状态变量和函数)。此外,stateStyles结合@Styles可根据组件状态动态设置样式,增强灵活性。通过实例演示了这些工具在实际开发中的应用,帮助开发者优化样式管理与维护效率。
89 9
|
22天前
|
HarmonyOS:ComposeTitleBar 组件自学指南
本文详解了鸿蒙开发中 ComposeTitleBar 组件的使用方法与技巧,从基础导入到属性配置,再到实际代码示例,帮助开发者构建美观实用的标题栏。组件自 API Version 10 起支持,具备独立功能结构,核心属性包括 `title`(必填)、`subtitle`(可选)和 `menuItems`(右侧菜单列表)。文章通过具体示例展示了如何配置标题、副标题及菜单项,并提供了交互优化、样式定制与多设备适配的建议。掌握这些内容,可显著提升应用界面体验。如果你有所收获,别忘了点赞收藏!
41 8
鸿蒙栅格布局组件 GridRow 自学指南
在鸿蒙应用开发中,布局设计常因设备分辨率差异而面临挑战。传统固定布局可能导致组件挤压或显示错乱,而 GridRow 组件提供了灵活解决方案。它从 API Version 9 起支持栅格布局,搭配 GridCol 子组件实现强大适配能力。本文详解 GridRow 的参数、属性与事件,如 `columns`、`gutter`、`breakpoints` 等,并通过实战示例展示其应用。掌握 GridRow,助你轻松应对多尺寸设备布局需求,打造精美界面。
46 7
|
26天前
|
HarmonyOS:动画 motionPath 、 animateToImmediately API自学指南
在鸿蒙应用开发中,动画是提升用户体验的关键。本文针对初学者面对众多动画API时的困惑,重点解析两个实用API:`motionPath`和`animateToImmediately`。前者通过精细控制组件运动路径(如SVG字符串定义轨迹),实现灵动位移动画;后者从API Version 12起支持显式动画立即下发,结合状态变化打造流畅动画序列。文中提供详细参数说明与示例代码,帮助开发者快速掌握技巧,让应用更生动。
56 8
HarmonyOS:ArkTS 显式动画 animateTo 自学指南
本文深入解析了 ArkTS 中的 `animateTo` 全局显式动画接口,帮助开发者掌握其使用方法。文章从接口概述、参数详解到使用注意事项,结合实际示例代码,全面展示了如何通过配置 `AnimateParam` 对象实现流畅的动画效果。内容涵盖属性动画、布局变化及组件转场等场景,并强调不同版本的支持特性。适合初学者系统学习,也供进阶开发者参考优化动画体验。希望本文能助你快速上手 `animateTo`!
81 7
HarmonyOS @Reusable 装饰器自学指南:高性能组件复用实战指南
在 HarmonyOS 开发中,组件性能优化至关重要。本文聚焦 @Reusable 装饰器的组件复用机制,从核心原理到实战场景深入解析。通过列表性能优化、复杂布局动态更新等案例,结合生命周期管理与状态策略,提供系统化学习路径。同时,针对常见问题提出解决方案,并给出架构设计建议。掌握 @Reusable 不仅能提升性能(实测 30%-50%),还能优化开发流程。适合开发者进阶参考!
56 0
HarmonyOS人脸比对技术自学指南与实战分享
本文详解了如何基于HarmonyOS Core Vision Kit实现人脸相似度比对功能,适用于娱乐类APP开发。通过`faceComparator`模块,简化了检测、特征提取与比对流程,支持端侧离线处理。文章涵盖技术架构解析、开发准备、UI设计及核心逻辑实现,并提供性能优化、异常处理及多人比对扩展方案。重点包括置信度分级、LRU缓存、隐私合规设计,助力开发者快速构建高效稳定的功能。
52 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等