HarmonyOS鸿蒙Next中请教一个动态修改组件高度,组件内子元素动画问题
HarmonyOS鸿蒙Next中请教一个动态修改组件高度,组件内子元素动画问题 下面组件代码,为啥只有展开的时候文本内容会随 Row 高度变化逐渐显示,隐藏的时候没有这个动画效果,文本直接就隐藏了
SDK:HarmonyOS 5.1.0 Release SDK
API版本:Version 18 Release
@Entry
@ComponentV2
struct TestPage {
private content =
'文本内容,文本内容,文本内容,文本内容,文本内容,文本内容'
@Local status: boolean = true
build() {
Column() {
Row() {
Text(this.status ? '隐藏' : '展示')
.margin({
bottom: 10
})
.onClick(() => {
this.status = !this.status
})
}
.width('100%')
Row() {
Text(this.content)
.width('100%')
}
.width('100%')
.height(this.status ? 200 : 0)
.clip(true)
.alignItems(VerticalAlign.Top)
.animation({
duration: 1000,
curve: Curve.EaseInOut
})
}
.width('100%')
}
}
更多关于HarmonyOS鸿蒙Next中请教一个动态修改组件高度,组件内子元素动画问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
因为你隐藏的时候高度直接设置为0,这样会导致组件的属性动画失效
可以这么写,加多一个显隐控制,且高度不置为0
@Entry
@ComponentV2
struct TestPage {
private content =
'文本内容,文本内容,文本内容,文本内容,文本内容,文本内容'
@Local status: boolean = true
build() {
Column() {
Row() {
Text(this.status ? '隐藏' : '展示')
.margin({
bottom: 10
})
.onClick(() => {
this.status = !this.status
})
}
.width('100%')
Row() {
Text(this.content)
.width('100%')
}
.width('100%')
.height(this.status ? 200 : 'auto')
.visibility(this.status ?Visibility.Visible:Visibility.None)
.clip(true)
.alignItems(VerticalAlign.Top)
.animation({
duration: 1000,
curve: Curve.EaseInOut
})
}
.width('100%')
}
}
| 名称 | 说明 |
|---|---|
| Hidden | 隐藏,但参与布局进行占位。 |
| Visible | 显示。 |
| None | 隐藏,但不参与布局,不进行占位。 |
更多关于HarmonyOS鸿蒙Next中请教一个动态修改组件高度,组件内子元素动画问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas的内容等,如果要内容跟随宽高变化,可以使用renderFit属性配置。
@Entry
@Component
struct RenderFitExample {
@State width1: number = 100;
@State height1: number = 30;
flag: boolean = true;
build() {
Column() {
Text("Hello")
.width(this.width1)
.height(this.height1)
.borderWidth(1)
.textAlign(TextAlign.Start)
.renderFit(RenderFit.LEFT)// 设置LEFT的renderFit,动画过程中,动画的终态内容与组件保持左对齐
.margin(20)
Text("Hello")
.width(this.width1)
.height(this.height1)
.textAlign(TextAlign.Center)
.borderWidth(1)
.renderFit(RenderFit.CENTER)// 设置CENTER的renderFit,动画过程中,动画的终态内容与组件保持中心对齐
.margin(20)
Button("animate")
.onClick(() => {
this.getUIContext()?.animateTo({ curve: Curve.Ease }, () => {
if (this.flag) {
this.width1 = 150;
this.height1 = 50;
} else {
this.width1 = 100;
this.height1 = 0;
}
this.flag = !this.flag;
})
})
}.width("100%").height("100%").alignItems(HorizontalAlign.Center)
}
}


尝试了一下, height 设置为 0 的时候不好使,如果设置成 1 就可以,为啥呢
在HarmonyOS Next中,使用animateTo方法实现动态修改组件高度时的子元素动画。通过状态变量控制组件高度,在animateTo动画闭包内更新状态,子元素会自动应用平滑过渡效果。关键代码示例:
@State height: number = 100
...
Button("点击动画")
.onClick(() => {
animateTo({ duration: 500 }, () => {
this.height = this.height === 100 ? 200 : 100
})
})
...
Column() {
// 子组件内容
}
.height(this.height)
动画参数可通过animateTo的options参数配置曲线与时长。
这是因为在折叠时,Row组件的高度从200变为0,同时clip属性为true,导致文本内容被直接裁剪隐藏,没有过渡动画。
问题在于:当高度变为0时,即使设置了animation,文本内容也会因为clip裁剪而立即消失,无法显示逐渐隐藏的动画效果。
解决方案:可以尝试以下两种方式:
- 使用opacity属性配合动画:
.height(this.status ? 200 : 0)
.opacity(this.status ? 1 : 0)
.clip(true)
.animation({
duration: 1000,
curve: Curve.EaseInOut
})
- 或者使用布局约束和margin/padding来实现折叠效果,避免高度直接变为0:
.height(this.status ? 200 : 1) // 最小高度保持1,避免完全裁剪
.clip(true)
.animation({
duration: 1000,
curve: Curve.EaseInOut
})
这样在折叠时文本内容会有一个渐隐的过渡效果,而不是直接消失。

