项目演示

在这里插入图片描述
在这里插入图片描述

一、什么是「隐式动画」

在 ArkUI 声明式开发范式下,UI 是数据驱动的:当被 @State@Prop@Link@Provide 等装饰的状态变量发生变化时,build() 会被重新执行,组件树上对应的属性(宽高、颜色、位置、透明度等)也会随之更新。

显式动画(如 animateTo)需要开发者显式调用,并在闭包内主动修改属性;而隐式动画animation 属性方法)则把动画能力直接「贴」在组件的属性链上——只要位于 animation() 之前的可动画属性发生变化,系统就会自动按设定的时长和曲线进行补间过渡

一句话总结:

隐式动画 = 「属性变化」+「animation 声明」→ 系统自动补间。

这种写法更贴近声明式 UI 的心智模型,开发者只需关心「终态值」,过渡过程由系统完成,代码更简洁、可读性更高。


二、API 24 中的 animation 接口签名

在 API 24 中,animationCommonAttribute 上的通用属性方法,几乎所有组件都可调用。其签名为:

animation(value: AnimateParam): T

AnimateParam 是动画参数结构体,在 API 24 中定义如下:

interface AnimateParam {
  duration: number;                 // 动画时长,单位 ms,默认 1000,建议范围 0~30000
  tempo?: number;                   // 播放速率,默认 1.0,>1 加速,<1 减速
  curve?: Curve | string | ICurve;  // 动画曲线,默认 Curve.Linear
  delay?: number;                   // 延迟播放时间,单位 ms,默认 0
  iterations?: number;              // 播放次数,默认 1;-1 表示无限循环
  playMode?: PlayMode;              // 播放模式,默认 PlayMode.Normal
  onFinish?: () => void;            // 动画结束回调
  onFinishFrame?: (frame: number) => void; // API 24 新增:每帧结束回调(frame 为帧索引)
  expect?: () => void;              // API 24 新增:期望态回调,用于自适应动画
}

参数详解

2.1 duration(时长)
  • 单位毫秒(ms),默认 1000。
  • 取值范围建议 0~30000;过大可能导致补间不流畅,过小则看不出过渡。
  • duration = 0 时,等同于「立即跳变」,不会产生动画效果。
2.2 curve(动画曲线)

curve 决定属性值随时间变化的「节奏」,是动画表现力的核心。API 24 支持三种写法:

① 内置 Curve 枚举(最常用,零依赖)

enum Curve {
  Linear,              // 匀速
  Ease,                // 起止平滑
  EaseIn,              // 先慢后快
  EaseOut,             // 先快后慢
  EaseInOut,           // 两端平滑
  FastOutSlowIn,       // 快出慢入(推荐默认值,Material 风格)
  LinearOutSlowIn,     // 慢入匀速出
  FastOutLinearIn,     // 匀速入快出
  ExtremeDeceleration, // 极端减速
  Sharp,               // 锐利
  Rhythm,              // 节奏
  Smooth,              // 平滑
  Bouncing             // 弹跳
}

② 字符串形式

curve: 'ease-in-out'

ICurve 对象(来自 @kit.ArkUI 的 curves 模块)

适合需要自定义贝塞尔、弹簧、共振曲线的高级场景:

import { curves } from '@kit.ArkUI';

curve: curves.cubicBezierCurve(0.42, 0, 0.58, 1)   // 三次贝塞尔
curve: curves.springCurve({ mass: 1, stiffness: 200, damping: 15 }) // 弹簧
curve: curves.responsiveSpringMotion()              // 响应式弹簧

⚠️ 注意:API 24 中 curves 模块的方法名以 ...Curve 结尾(如 cubicBezierCurvespringCurve),旧版本中的 cubicBezierspringfastOutSlowIn 等不带 Curve 后缀的写法已废弃或不存在,编译会报 Property 'xxx' does not exist on type 'typeof curves' 错误。这也是初学者最常踩的坑。

2.3 tempo(播放速率)
  • 默认 1.0。
  • tempo = 2 表示 2 倍速播放(实际时长 = duration / tempo)。
  • 取值需 > 0,为 0 或负数会导致行为未定义。
2.4 delay(延迟)
  • 延迟多少毫秒后开始播放,默认 0。
  • 适合做「错峰动画」,例如列表项依次入场。
2.5 iterations(迭代次数)
  • 默认 1。
  • 设为 -1 表示无限循环,常用于 loading 呼吸、脉冲效果。
  • 设为 3 表示播放 3 次后停止。
2.6 playMode(播放模式)
enum PlayMode {
  Normal,       // 正向播放
  Reverse,      // 反向播放
  Alternate,    // 正反交替(第 1 次正向,第 2 次反向…)
  AlternateReverse // 反正交替
}

iterations > 1 时,Alternate 可实现「来回」效果。

2.7 onFinish / onFinishFrame(回调)
  • onFinish:整个动画结束时触发一次。
  • onFinishFrame:API 24 新增,每一帧补间完成都会触发,参数 frame 为帧序号。可用于做与动画同步的副作用(如音效、粒子)。

三、animation 的核心规则:调用顺序

这是隐式动画最关键、也最容易踩坑的点,必须牢记:

规则 1:animation() 只对它之前声明的可动画属性生效

// ✅ 正确:可动画属性在前,animation 紧随其后
Column()
  .width(this.boxWidth)       // 可动画
  .height(this.boxHeight)     // 可动画
  .backgroundColor(this.bg)   // 可动画
  .opacity(this.op)           // 可动画
  .animation({                // ← 监听以上 4 个属性
    duration: 800,
    curve: Curve.FastOutSlowIn
  })
  .justifyContent(FlexAlign.Center)  // 非动画属性,写在 animation 之后
// ❌ 错误:animation 写在属性之前,动画不会生效
Column()
  .animation({ duration: 800, curve: Curve.Linear })
  .width(this.boxWidth)   // animation 之后,不会被监听

规则 2:非可动画属性即使写在 animation 之前也不会产生动画

justifyContentalignItemsmargin 等布局属性本身不支持补间,即使写在 animation 前面也不会触发动画,但也不会报错——它们会瞬时变化。

规则 3:animation 可叠加多个

可以为一个组件声明多个 animation,每个 animation 监听其前方、且未被前一个 animation 监听的属性,从而实现「不同属性用不同曲线」:

Column()
  .width(this.w)
  .animation({ duration: 300, curve: Curve.Linear })   // 监听 width,用 Linear
  .backgroundColor(this.bg)
  .animation({ duration: 800, curve: Curve.EaseInOut }) // 监听 bgColor,用 EaseInOut

四、可动画属性清单(API 24)

并非所有属性都支持隐式动画。下面是 API 24 中常用可动画属性分类:

类别 属性 说明
几何 width、height、size 尺寸过渡
位置 position、markAnchor、offset 位移(不影响布局)
变换 scale、rotate、translate、transform 仿射变换
外观 opacity 透明度
背景 backgroundColor、backgroundImagePosition、backgroundImageSize 背景相关
边框 borderColor、borderRadius、borderWidth 边框
阴影 shadow 阴影颜色/偏移/半径
文本 fontSize、fontColor、fontWeight、letterSpacing 文本属性
渐变 linearGradient 内的 angle、colors 偏移 渐变动画
其他 color、visibility(部分场景) 通用属性

提示:visibilityHiddenVisible 之间是「显隐切换」而非补间;如需淡入淡出,请用 opacity 实现。


五、最小可运行示例

下面是一个 80 行的最小示例,演示「点击 → 属性变化 → 自动触发动画」。

// MinimalAnimationDemo.ets
@Entry
@Component
struct MinimalAnimationDemo {
  @State scaleValue: number = 1;
  @State bgColor: ResourceColor = '#4CAF50';

  build() {
    Column({ space: 30 }) {
      // 可动画方块
      Column() {
        Text('点我')
          .fontSize(24)
          .fontColor(Color.White)
      }
      .width(160)
      .height(160)
      .backgroundColor(this.bgColor)
      .borderRadius(20)
      .scale({ x: this.scaleValue, y: this.scaleValue })
      .animation({
        duration: 600,
        curve: Curve.FastOutSlowIn
      })
      .justifyContent(FlexAlign.Center)
      .onClick(() => {
        // 点击同时改变 scale 和颜色,animation 自动补间
        this.scaleValue = this.scaleValue === 1 ? 1.4 : 1;
        this.bgColor = this.bgColor === '#4CAF50' ? '#E91E63' : '#4CAF50';
      })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

运行效果:点击方块时,缩放与颜色变化会以 600ms 的快出慢入曲线平滑过渡,而非瞬间跳变。


六、进阶示例:多属性综合演示

下面给出一个相对完整的示例,覆盖 6 类可动画属性,并配有控制按钮。这也是本文配套的 AnimationImplicitDemo.ets 文件核心逻辑(API 24 校正版)。

// AnimationImplicitDemo.ets
@Entry
@Component
struct AnimationImplicitDemo {
  @State scaleValue: number = 1;
  @State rotateAngle: number = 0;
  @State translateX: number = 0;
  @State opacityValue: number = 1;
  @State boxWidth: number = 200;
  @State boxHeight: number = 200;
  @State bgColor: ResourceColor = '#4CAF50';
  @State radiusValue: number = 16;

  build() {
    Column() {
      Text('animation 隐式动画布局')
        .fontSize(22).fontWeight(FontWeight.Bold)
        .margin({ top: 24, bottom: 16 })

      // 动画展示区:所有可动画属性写在 animation 之前
      Column() {
        Text('ArkTS').fontSize(28).fontColor(Color.White)
      }
      .width(this.boxWidth)
      .height(this.boxHeight)
      .backgroundColor(this.bgColor)
      .borderRadius(this.radiusValue)
      .opacity(this.opacityValue)
      .scale({ x: this.scaleValue, y: this.scaleValue })
      .rotate({ angle: this.rotateAngle })
      .translate({ x: this.translateX })
      .animation({
        duration: 800,
        curve: Curve.FastOutSlowIn,
        iterations: 1,
        playMode: PlayMode.Normal
      })
      .justifyContent(FlexAlign.Center)
      .margin({ top: 20, bottom: 30 })

      // 缩放按钮
      Button('缩放 +0.5').type(ButtonType.Capsule).backgroundColor('#2196F3')
        .onClick(() => {
          this.scaleValue = this.scaleValue >= 2 ? 1 : this.scaleValue + 0.5;
        })

      // 旋转按钮
      Button('旋转 +90°').type(ButtonType.Capsule).backgroundColor('#FF9800')
        .onClick(() => { this.rotateAngle += 90; })

      // 平移按钮
      Button('左右平移').type(ButtonType.Capsule).backgroundColor('#9C27B0')
        .onClick(() => {
          this.translateX = this.translateX === 0 ? 80 : 0;
        })

      // 透明度按钮
      Button('透明度切换').type(ButtonType.Capsule).backgroundColor('#F44336')
        .onClick(() => {
          this.opacityValue = this.opacityValue === 1 ? 0.3 : 1;
        })

      // 尺寸按钮
      Button('尺寸切换').type(ButtonType.Capsule).backgroundColor('#009688')
        .onClick(() => {
          if (this.boxWidth === 200) {
            this.boxWidth = 280; this.boxHeight = 140;
          } else {
            this.boxWidth = 200; this.boxHeight = 200;
          }
        })

      // 颜色 + 圆角按钮
      Button('变色 + 圆角').type(ButtonType.Capsule).backgroundColor('#795548')
        .onClick(() => {
          if (this.bgColor === '#4CAF50') {
            this.bgColor = '#E91E63'; this.radiusValue = 80;
          } else {
            this.bgColor = '#4CAF50'; this.radiusValue = 16;
          }
        })

      // 一键重置
      Button('重置全部').type(ButtonType.Capsule).backgroundColor('#607D8B')
        .margin({ top: 16 })
        .onClick(() => {
          this.scaleValue = 1; this.rotateAngle = 0; this.translateX = 0;
          this.opacityValue = 1; this.boxWidth = 200; this.boxHeight = 200;
          this.bgColor = '#4CAF50'; this.radiusValue = 16;
        })
    }
    .width('100%').height('100%')
    .backgroundColor('#F5F5F5')
    .alignItems(HorizontalAlign.Center)
  }
}

代码要点解读

  1. 8 个 @State 变量分别驱动 8 个可动画属性,互不干扰。
  2. animation 只声明一次,它统一监听其上方的 8 个属性;任一属性变化都按 800ms / FastOutSlowIn 补间。
  3. **「重置全部」**一次性改 8 个变量,系统会同时对所有变化的属性进行补间,形成「复位动画」。
  4. 按钮的 backgroundColor 写在 animation 之前,但按钮没有声明 animation,因此按钮颜色是瞬时切换——这正是「是否补间取决于组件自身是否声明 animation」的体现。

七、curve 曲线选型指南

不同曲线带来的观感差异巨大,选型建议如下:

场景 推荐曲线 理由
入场动画(淡入、放大) Curve.EaseOutFastOutSlowIn 先快后慢,自然落位
退场动画(淡出、缩小) Curve.EaseIn 先慢后快,有「离开」倾向
加载呼吸、脉冲 Curve.Smooth + iterations: -1 平滑循环,无突兀感
弹性反馈(点赞、点赞取消) curves.springCurve(...) 物理弹簧,更有生命力
列表项错峰入场 Curve.FastOutLinearIn + 递增 delay 节奏明快
拖拽跟随 curves.responsiveSpringMotion() 响应式弹簧,跟随手感

弹簧曲线示例(API 24 写法)

import { curves } from '@kit.ArkUI';

// 在组件属性链中
.scale({ x: this.s, y: this.s })
.animation({
  duration: 1000,
  curve: curves.springCurve({ mass: 1, stiffness: 200, damping: 15 })
})

弹簧曲线下,duration 仅作为上限参考,实际时长由物理参数决定。


八、隐式动画 vs 显式动画(animateTo)

两者各有适用场景,理解差异才能选对工具。

维度 隐式动画 animation 显式动画 animateTo
触发方式 属性值变化自动触发 显式调用 animateTo 闭包
写法位置 组件属性链中 业务逻辑中
终态来源 来自状态变量绑定 在闭包内修改状态
多组件联动 需各自声明 animation 一个闭包可驱动多处
关键帧 不支持 配合 keyframeAnimateTo 支持
适合场景 简单属性过渡、交互反馈 复杂时序、组合动画

经验法则:能用隐式动画解决的,优先用隐式动画;需要精确时序控制或多组件协同的,再上 animateTo

显式动画对照示例

// 显式动画写法(对照用)
Button('放大')
  .onClick(() => {
    animateTo({ duration: 600, curve: Curve.FastOutSlowIn }, () => {
      this.scaleValue = 1.4;   // 在闭包内修改终态
    });
  })

对比可见,隐式动画把「终态」直接写在属性绑定里,业务代码只需改 this.scaleValue,无需包裹闭包,更符合数据驱动的范式。


九、常见踩坑与解决方案

坑 1:animation 写在属性之后没生效

现象:点击按钮属性变了,但是「跳变」没有过渡。

原因animation 写在了被监听属性之前。

解决:把 animation 移到所有可动画属性之后、非动画属性之前。

坑 2:curves.fastOutSlowIn 编译报错

现象Property 'fastOutSlowIn' does not exist on type 'typeof curves'

原因:API 24 中 curves 模块方法名以 Curve 结尾,旧写法已废弃。

解决

  • 简单场景直接用 Curve.FastOutSlowIn 枚举;
  • 自定义曲线用 curves.cubicBezierCurve(...)curves.springCurve(...) 等带 Curve 后缀的方法。

坑 3:列表项动画「同时」播放

现象:列表 10 项一起入场,没有错峰感。

解决:用 delay 配合索引递增:

ForEach(this.items, (item, idx) => {
  ItemView({ item })
    .animation({ duration: 400, delay: idx * 60, curve: Curve.EaseOut })
})

坑 4:循环动画卡顿

现象iterations: -1 时首尾衔接不平滑。

原因:起止值不对称,导致每次循环有「跳变」。

解决:使用 playMode: PlayMode.Alternate,让动画正反交替,自然衔接;或确保起止值相同。

坑 5:visibility 无法淡入淡出

现象:期望元素淡出消失,结果直接「闪没」。

原因visibility 不支持补间。

解决:用 opacity 配合动画完成淡出,在 onFinish 回调里再把 visibility 设为 Hidden

.opacity(this.visible ? 1 : 0)
.animation({
  duration: 300,
  curve: Curve.EaseOut,
  onFinish: () => {
    if (!this.visible) this.realHidden = true;
  }
})
.visibility(this.realHidden ? Visibility.Hidden : Visibility.Visible)

坑 6:animation 影响首次布局

现象:页面首次加载时组件也跑了一次动画。

原因@State 初值 → 首帧渲染,部分情况下会触发补间。

解决:用 if 条件渲染控制首帧,或在 aboutToAppear 中先设置终态、再切到初值;也可用 animateTo 显式控制首次出现。


十、性能优化建议

  1. 优先用变换属性scalerotatetranslate 不触发重排,性能远高于 width/height/margin。能用变换实现的,不要改尺寸。
  2. 避免同时对 8+ 属性做动画:单组件动画属性越多,每帧计算成本越高。核心视觉属性 ≤ 4 个为宜。
  3. duration 不宜过长:超过 1000ms 的动画容易让用户感到「迟钝」,交互反馈类建议 200~400ms。
  4. 合理使用 iterations:无限循环动画会持续占 GPU,组件不可见时记得置为 1 或卸载。
  5. onFinishFrame 谨慎使用:API 24 的逐帧回调若内部逻辑过重,会拖垮动画帧率。
  6. 列表中慎用复杂动画:长列表每项都声明 animation 会显著增加开销,建议只对「可视区+前后缓冲区」做动画。

十一、实战场景:点赞弹性反馈

下面用隐式动画实现一个类似「点赞」的弹性反馈,体现 scale + 颜色 + 弹簧曲线的组合。

// LikeButtonDemo.ets
import { curves } from '@kit.ArkUI';

@Entry
@Component
struct LikeButtonDemo {
  @State liked: boolean = false;
  @State scaleValue: number = 1;
  @State iconColor: ResourceColor = '#999999';

  build() {
    Column({ space: 40 }) {
      Text(liked ? '❤ 已点赞' : '♡ 点个赞吧')
        .fontSize(20)
        .fontColor(liked ? '#E91E63' : '#666666')

      // 点赞图标
      Text(liked ? '❤' : '♡')
        .fontSize(80)
        .fontColor(this.iconColor)
        .scale({ x: this.scaleValue, y: this.scaleValue })
        .animation({
          duration: 800,
          curve: curves.springCurve({ mass: 1, stiffness: 400, damping: 12 })
        })
        .onClick(() => {
          this.liked = !this.liked;
          // 通过先放大再回弹的「两段式终态」实现弹跳感
          this.scaleValue = this.liked ? 1.6 : 0.8;
          this.iconColor = this.liked ? '#E91E63' : '#999999';
          // 短延迟后回弹到 1.0,触发第二次补间
          setTimeout(() => { this.scaleValue = 1; }, 120);
        })
    }
    .width('100%').height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

要点

  • springCurve 物理曲线代替线性,自带「过冲」弹性。
  • 通过 setTimeout 制造「放大 → 回弹」两段终态,每次赋值都会触发一次补间,形成连续弹跳。
  • fontColoriconColor 同步过渡,颜色与缩放共享同一段 animation。

十二、实战场景:卡片翻转

利用 rotate 的 Y 轴旋转 + 透明度切换,模拟卡片翻转:

// CardFlipDemo.ets
@Entry
@Component
struct CardFlipDemo {
  @State flipped: boolean = false;
  @State rotateY: number = 0;
  @State opacityVal: number = 1;
  @State cardText: string = '正面';

  build() {
    Column({ space: 30 }) {
      Column() {
        Text(this.cardText).fontSize(28).fontColor(Color.White)
      }
      .width(220).height(300)
      .backgroundColor(this.flipped ? '#3F51B5' : '#FF7043')
      .borderRadius(16)
      .rotate({ y: 1, angle: this.rotateY })   // 绕 Y 轴旋转
      .opacity(this.opacityVal)
      .animation({ duration: 600, curve: Curve.FastOutSlowIn })
      .justifyContent(FlexAlign.Center)

      Button('翻转卡片')
        .onClick(() => {
          // 旋转到 90° 时切换内容(视觉上「侧立」的瞬间)
          this.rotateY += 90;
          setTimeout(() => {
            this.flipped = !this.flipped;
            this.cardText = this.flipped ? '背面' : '正面';
          }, 300);
        })
    }
    .width('100%').height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

提示:ArkUI 的 rotate 默认绕中心轴旋转,绕 Y 轴 90° 时组件「侧立」几乎不可见,此时切换内容即可实现翻转错觉。若需真正的 3D 翻转,可结合 transform 矩阵或两块叠加卡片分别绕 Y 轴 ±90° 旋转。


十三、与 API 24 其他动画能力联动

API 24 的动画体系是一个完整的「矩阵」,animation 是其中最轻量的一环。理解它在体系中的定位,才能组合出更丰富的效果:

能力 接口 定位
隐式属性动画 animation 本文主角,轻量声明式
显式属性动画 animateTo 闭包驱动,可包含多条状态修改
关键帧动画 keyframeAnimateTo 多关键帧、不同曲线
组件转场 transition 插入/移除时的入场出场
共享元素转场 sharedTransition 页面间共享元素飞越
粒子 / 物理动画 particlespringMotion 高级特效
绑定手势动画 panGesture + responsiveSpringMotion 拖拽跟随

典型组合:隐式动画负责属性过渡,transition 负责组件插入/移除,二者互补。例如:

if (this.showBadge) {
  Text('NEW')
    .transition({ type: TransitionType.All, opacity: 0, translate: { y: -20 } })
    .opacity(this.badgeOpacity)
    .animation({ duration: 300, curve: Curve.EaseOut })
}

十四、小结

animation 隐式动画布局是 ArkUI 声明式范式中「最贴近数据驱动心智」的动画方式。掌握它的关键在于三件事:

  1. 顺序:可动画属性在前,animation 紧随其后,非动画属性再写后面。
  2. 曲线:用 Curve 枚举应对 90% 场景,用 curves.xxxCurve 处理物理曲线,注意 API 24 方法名带 Curve 后缀。
  3. 属性选型:优先用 scale/rotate/translate/opacity 等变换类属性,性能最佳;width/height/margin 等布局属性次之;visibility 等不支持补间的属性要用 opacity 间接实现。

把这三点内化后,绝大多数交互反馈、状态过渡都能用 3~5 行 animation 优雅解决,无需复杂的显式动画代码。


附录 A:完整可运行工程结构

entry/src/main/ets/pages/
├── Index.ets                       # 入口页,提供跳转按钮
├── AnimationImplicitDemo.ets       # 多属性综合演示(第六章)
├── MinimalAnimationDemo.ets        # 最小示例(第五章)
├── LikeButtonDemo.ets              # 点赞弹性反馈(第十一章)
└── CardFlipDemo.ets                # 卡片翻转(第十二章)

entry/src/main/resources/base/profile/main_pages.json
{
  "src": [
    "pages/Index",
    "pages/AnimationImplicitDemo",
    "pages/MinimalAnimationDemo",
    "pages/LikeButtonDemo",
    "pages/CardFlipDemo"
  ]
}

附录 B:API 24 curves 模块常用方法速查

方法 用途
curves.cubicBezierCurve(x1, y1, x2, y2) 三次贝塞尔曲线
curves.springCurve({ mass, stiffness, damping, velocity }) 物理弹簧
curves.springMotion(response, dampingFraction, overlapDuration) 弹簧运动(适合手势)
curves.responsiveSpringMotion(response, dampingFraction, overlapDuration) 响应式弹簧运动
curves.customCurve(...) 自定义插值函数

旧写法 curves.cubicBeziercurves.springcurves.fastOutSlowIncurves.easeIn 等在 API 24 中已废弃或不存在,请统一改用带 Curve 后缀的新方法,或直接使用 Curve 枚举。

附录 C:Curve 枚举速查表

枚举值 别名 表现
Curve.Linear linear 匀速
Curve.Ease ease 起止平滑
Curve.EaseIn ease-in 先慢后快
Curve.EaseOut ease-out 先快后慢
Curve.EaseInOut ease-in-out 两端平滑
Curve.FastOutSlowIn 快出慢入(推荐默认)
Curve.LinearOutSlowIn 匀速入慢出
Curve.FastOutLinearIn 快入匀速出
Curve.ExtremeDeceleration 极端减速
Curve.Sharp 锐利
Curve.Rhythm 节奏
Curve.Smooth 平滑
Curve.Bouncing 弹跳

版本声明:本文所有 API、参数、方法名均以 HarmonyOS NEXT API 24 为准。后续版本如有变更,请以官方文档为准。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐