HarmonyOS鸿蒙Next中当宽度高度是"auto"或者是自适应,尺寸发生变化,变化过程如何增加动画
HarmonyOS鸿蒙Next中当宽度高度是"auto"或者是自适应,尺寸发生变化,变化过程如何增加动画 当宽度高度是"auto"或者是自适应,尺寸发生变化,变化过程如何增加动画
【解决方案】
开发者你好,组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor等。animateTo显式动画提供全局接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态。参考以下方案:
- 方案一:通过animation属性配置动画参数对象,包含:
- duration:动画持续时间(单位ms);
- curve:缓动曲线(默认线性);
- iterations:重复次数(0表示无限);
- delay:执行延迟时间。
注意,属性动画只对写在animation前面的属性生效,且对组件构造器的属性不生效。 完整代码如下:
@Entry
@Component
struct Index {
@State widthSize: number | string = '100%'
build() {
Column() {
Column()
.width(this.widthSize)
.height(300)
.backgroundColor(Color.Orange)
.animation({
duration: 2000,
curve: Curve.EaseOut,
iterations: 1,
playMode: PlayMode.Normal
})
.onClick(() => {
this.widthSize = this.widthSize === 44 ? '100%' : 44;
})
}
.width('100%')
.margin({ top: 20 })
.alignItems(HorizontalAlign.Start)
}
}
- 方案二:通过animateTo显示动画参数对象,包含:
- duration:动画持续时间(单位ms);
- curve:缓动曲线(默认线性);
- iterations:重复次数(0表示无限);
- delay:执行延迟时间;
- event:指定动效的闭包函数。
完整代码如下:
@Entry
@Component
struct NavigatorBase {
@State widthSize: number | string = '100%'
build() {
Column() {
Column()
.width(this.widthSize)
.height(300)
.backgroundColor(Color.Orange)
.onClick(() => {
this.getUIContext()?.animateTo({
duration: 2000,
curve: Curve.EaseOut,
iterations: 1,
playMode: PlayMode.Normal
}, () => {
this.widthSize = this.widthSize === 44 ? '100%' : 44;
})
})
}
.width('100%')
.margin({ top: 20 })
.alignItems(HorizontalAlign.Start)
}
}
更多关于HarmonyOS鸿蒙Next中当宽度高度是"auto"或者是自适应,尺寸发生变化,变化过程如何增加动画的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
看下属性动画
使用animalTo,闭包内写改变属性引起的界面变化的代码,会自动计算属性的变化,不需要开发者自己计算
在HarmonyOS鸿蒙Next中,当组件的宽度或高度设置为"auto"或自适应时,尺寸变化可通过属性动画实现。使用animateTo方法,在状态变量改变时包裹尺寸属性更新代码,系统会自动在旧尺寸与新尺寸之间生成平滑过渡动画。关键是在animateTo闭包内修改触发布局变化的响应式状态变量。
在HarmonyOS Next中,为自适应尺寸(auto)变化添加动画,核心是使用动画组件包裹内容,并驱动布局属性的变化。以下是关键方法:
1. 使用显式动画驱动布局变化
当尺寸由内容决定时,直接对width/height设置动画可能无效。推荐使用布局过渡动画:
- 通过状态变量(
@State)控制内容变化(如文本、子组件显隐)。 - 用动画组件(如
animateTo)包裹状态变化,系统会自动对布局变化过程进行插值。
示例:文本展开/收起动画
@State isExpanded: boolean = false
// 控制显示全文或摘要文本
build() {
Column() {
Text(this.isExpanded ? longText : shortText)
.transition(TransitionEffect.OPACITY.animation({ duration: 300 }))
Button('Toggle')
.onClick(() => {
// 动画驱动布局重计算
animateTo({ duration: 500 }, () => {
this.isExpanded = !this.isExpanded
})
})
}
}
2. 结合自定义组件的size属性动画
对于自定义组件,可在aboutToAppear或状态更新时,通过animateTo动态计算并设置明确尺寸:
@State private containerWidth: number = 0
private measuredWidth: number = 0
build() {
Column()
.onAreaChange((oldArea, newArea) => {
// 监听区域变化获取实际宽度
this.measuredWidth = newArea.width
})
.width(this.containerWidth) // 绑定动画变量
}
// 触发动画
animateTo({ duration: 400 }, () => {
this.containerWidth = this.measuredWidth // 从0到实际宽度过渡
})
3. 使用Transition组件处理复杂场景
若子组件结构变化引起尺寸自适应,可用Transition控制进入/退出动画:
Transition(this.isExpanded, {
// 定义出现和消失动画
if: expandAnimation(),
ifNot: collapseAnimation()
}) {
// 内容区域
ComplexContentComponent()
}
注意事项
- 避免直接对
auto值做动画:应动画驱动导致尺寸变化的根本原因(如内容、约束条件)。 - 性能优化:对于连续变化(如文本输入),建议使用
animation修饰符设置曲线动画而非频繁触发animateTo。 - 嵌套布局确保父容器允许尺寸变化(如
Column未设置固定高宽)。
通过动画驱动状态而非直接干预布局属性,可让自适应尺寸的变化过程自然平滑。

