class="hide-preCode-box">

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
在对组件位置或大小变化做动画时,由于布局属性的改变会触发重新测量布局,导致性能开销大。scale属性的改变不会重新触发测量布局,性能开销小。因此,在组件位置大小持续发生变化的场景,如手指缩放的动画场景,推荐使用scale。
正例:通过设置图形变换属性scale,改变组件大小。
@Entry
@Component
struct MyComponent {
@State textScaleX: number = 1;
@State textScaleY: number = 1;
build() {
Column() {
Text()
.backgroundColor(Color.Blue)
.fontColor(Color.White)
.fontSize(20)
.width(10)
.height(10)
.scale({ x: this.textScaleX, y: this.textScaleY })
.margin({ top: 100 })
Button('图形变换属性')
.backgroundColor(Color.Blue)
.fontColor(Color.White)
.fontSize(20)
.margin({ top: 60 })
.borderRadius(30)
.padding(10)
.onClick(() => {
animateTo({ duration: 1000 }, () => {
this.textScaleX = 10;
this.textScaleY = 10;
})
})
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
动画参数相同时使用同一个animateTo
每次animateTo都需要进行动画前后的对比,因此,减少animateTo的使用次数(例如使用同一个animateTo设置组件属性),可以减少该组件更新的次数,从而获得更好的性能。
如果各个属性要做动画的参数相同,推荐将它们放到同一个动画闭包中执行。
反例:相同动画参数的状态变量更新放在不同的动画闭包中。
@Entry
@Component
struct MyComponent {
@State textWidth: number = 200;
@State color: Color = Color.Red;
func1() {
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.textWidth = (this.textWidth === 100 ? 200 : 100);
});
}
func2() {
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.color = (this.color === Color.Yellow ? Color.Red : Color.Yellow);
});
}
build() {
Column() {
Row()
.width(this.textWidth)
.height(10)
.backgroundColor(this.color)
Text('click')
.onClick(() => {
this.func1();
this.func2();
})
}
.width('100%')
.height('100%')
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
正例:将相同动画参数的动画合并在一个动画闭包中。
@Entry
@Component
struct MyComponent {
@State textWidth: number = 200;
@State color: Color = Color.Red;
func() {
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.textWidth = (this.textWidth === 100 ? 200 : 100);
this.color = (this.color === Color.Yellow ? Color.Red : Color.Yellow);
});
}
build() {
Column() {
Row()
.width(this.textWidth)
.height(10)
.backgroundColor(this.color)
Text('click')
.onClick(() => {
this.func();
})
}
.width('100%')
.height('100%')
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
多次animateTo时统一更新状态变量
animateTo会将执行动画闭包前后的状态进行对比,对差异部分进行动画。为了对比,会在执行animateTo的动画闭包之前,将所有变更的状态变量和脏节点都刷新。
如果多个animateTo之间存在状态更新,会导致执行下一个animateTo之前又存在需要更新的脏节点,可能造成冗余更新。
反例:多个animateTo之间更新状态变量。

以下代码在两个animateTo之间更新组件的其他状态。
@Entry
@Component
struct MyComponent {
@State textWidth: number = 200;
@State textHeight: number = 50;
@State color: Color = Color.Red;
build() {
Column() {
Row()
.width(this.textWidth)
.height(10)
.backgroundColor(this.color)
Text('click')
.height(this.textHeight)
.onClick(() => {
this.textWidth = 100;
this.textHeight = 100;
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.textWidth = 200;
});
this.color = Color.Yellow;
animateTo({ curve: Curve.Linear, duration: 2000 }, () => {
this.color = Color.Red;
});
})
}
.width('100%')
.height('100%')
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
在第一个animateTo前,重新设置了textWidth属性,所以Row组件需要更新一次。在第一个animateTo的动画闭包中,改变了textWidth属性,所以Row组件又需要更新一次并对比产生宽高动画。第二个animateTo前,重新设置了color属性,所以Row组件又需要更新一次。在第二个animateTo的动画闭包中,改变了color属性,所以Row组件再更新一次并产生了背景色动画。Row组件总共更新了4次属性。
此外还更改了与动画无关的状态textHeight,如果不需要改变无关状态,则不应改变造成冗余更新。
正例:统一更新状态变量。

正例1:在animateTo之前使用原始状态,让动画从原始状态过渡到指定状态,这样也能避免动画在开始时发生跳变。
@Entry
@Component
struct MyComponent {
@State textWidth: number = 100;
@State textHeight: number = 50;
@State color: Color = Color.Yellow;
build() {
Column() {
Row()
.width(this.textWidth)
.height(10)
.backgroundColor(this.color)
Text('click')
.height(this.textHeight)
.onClick(() => {
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.textWidth = (this.textWidth === 100 ? 200 : 100);
});
animateTo({ curve: Curve.Linear, duration: 2000 }, () => {
this.color = (this.color === Color.Yellow ? Color.Red : Color.Yellow);
});
})
}
.width('100%')
.height('100%')
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
在第一个animateTo之前,不存在需要更新的脏状态变量和脏节点,无需更新。在第一个animateTo的动画闭包中,改变了textWidth属性,所以Row组件需要更新一次并对比产生宽高动画。在第二个animateTo之前,由于也没有执行额外的语句,不存在需要更新的脏状态变量和脏节点,无需更新。在第二个animateTo的动画闭包中,改变了color属性,所以Row组件再更新一次并产生了背景色动画。Row组件总共更新了2次属性。
正例2:在animateTo之前显式的指定所有需要动画的属性初值,统一更新到节点中,然后再做动画。
@Entry
@Component
struct MyComponent {
@State textWidth: number = 200;
@State textHeight: number = 50;
@State color: Color = Color.Red;
build() {
Column() {
Row()
.width(this.textWidth)
.height(10)
.backgroundColor(this.color)
Text('click')
.height(this.textHeight)
.onClick(() => {
this.textWidth = 100;
this.color = Color.Yellow;
animateTo({ curve: Curve.Sharp, duration: 1000 }, () => {
this.textWidth = 200;
});
animateTo({ curve: Curve.Linear, duration: 2000 }, () => {
this.color = Color.Red;
});
this.textHeight = 100;
})
}
.width('100%')
.height('100%')
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
在第一个animateTo之前,重新设置了textWidth和color属性,所以Row需要更新一次。在第一个animateTo的动画闭包中,改变了textWidth属性,所以Row组件需要更新一次并对比产生宽高动画。在第二个animateTo之前,由于没有执行额外的语句,不存在需要更新的脏状态变量和脏节点,无需更新。在第二个animateTo的动画闭包中,改变了color属性,所以Row组件再更新一次并产生了背景色动画。Row组件总共更新了3次属性。
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙开发学习手册》:
- 基本概念
- 构建第一个ArkTS应用
- ……

- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……

- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……


1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/maniuT/article/details/138189290","extend1":"pc","ab":"new"}">>
id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"> class="blog_extension blog_extension_type2" id="blog_extension">
class="extension_official" data-report-click="{"spm":"1001.2101.3001.6471"}" data-report-view="{"spm":"1001.2101.3001.6471"}">
class="blog_extension_card_left">
class="blog_extension_card_cont">
鸿蒙开发学习资料领取!!!
class="blog_extension_card_cont_r">
微信名片
评论记录:
回复评论: