一、功能简介
本篇将实现点击卡片后展开或收起其内容区域的动画效果,结合动态高度过渡与箭头旋转,提升信息层级切换时的交互感,适用于 FAQ、订单详情、商品规格等场景。
二、关键动画能力点
能力 | 技术点 |
---|---|
高度过渡 | .height() 结合 .animate() |
动态内容控制 | If() 配合 @State 显示隐藏 |
图标旋转 | .rotate() 结合状态切换 |
动效曲线 | Curve.EaseInOut 提升流畅度 |
三、页面结构
entry/src/main/ets/pages/ExpandableCardDemo.ets
四、ArkTS 实战代码(ExpandableCardDemo.ets)
@Entry
@Component
struct ExpandableCardDemo {
@State expanded: boolean = false
build() {
Column() {
Text('HarmonyOS 5.0.0 或以上')
.fontSize(20)
.margin({ bottom: 16 })
Column() {
Row() {
Text('订单信息')
.fontSize(16)
.fontWeight(FontWeight.Bold)
Blank()
Image($r('app.media.ic_arrow_down'))
.width(20).height(20)
.rotate({ angle: this.expanded ? 180 : 0 })
.animate({ duration: 200 })
}
.onClick(() => this.expanded = !this.expanded)
.padding({ top: 12, bottom: 12 })
// 内容区域
Column() {
If(this.expanded, () => {
Column() {
Text('商品:HarmonyOS 智能路由器')
Text('价格:¥299')
Text('地址:广州市天河区软件路')
}
.fontSize(14)
.lineHeight(22)
.opacity(this.expanded ? 1 : 0)
.height(this.expanded ? 'auto' : 0)
.animate({ duration: 250, curve: Curve.EaseInOut })
})
}
.padding({ bottom: 12 })
}
.padding(16)
.backgroundColor('#ffffff')
.borderRadius(12)
.shadow({ radius: 4, color: '#ccc' })
}
.width('100%')
.padding(20)
.backgroundColor('#f3f3f3')
}
}
五、运行效果说明
-
点击标题行 → 展开下方内容;
-
再次点击 → 收起内容区域;
-
展开/收起伴随平滑高度变化;
-
箭头图标同步旋转增强引导性。
六、常见问题与优化建议
问题 | 表现 | 原因 | 解决方案 |
---|---|---|---|
内容闪现 | 切换逻辑提前渲染 | 使用 If() 结构包装内容区域 | |
折叠过快 | 动画未配置 | 添加 .animate() 并设置合适 duration | |
图标不同步 | 状态控制未绑定 | 图标角度由 @State expanded 统一控制 |
七、拓展建议
-
增加展开多个卡片的“手风琴模式”;
-
支持异步加载卡片内容(如首次展开加载详情);
-
多项卡片统一状态管理,形成嵌套列表;
-
引入滑动展开或长按展开行为;
-
可封装为通用组件
<ExpandableCard title="xx">...</ExpandableCard>
。
下一篇为第9篇:
《HarmonyOS 5.0.0 或以上:实现顶部导航栏进入与隐藏动画(滚动收缩)效果》