ArkUI 动画衔接:一个动作结束,下一个别抢跑
【摘要】 今天我们用 animateTo 的完成回调串两段动画。 很多动效看着乱,不是因为动画不够多,而是前一段还没结束,后一段已经抢着开始了。这个 Demo 只做两段:第一张卡片先滑出去,完成后第二张卡片再出现。 这个 Demo 看什么 核心在 startLinkage(): 第一段 animateTo 修改 firstDon
ArkUI 动画衔接:一个动作结束,下一个别抢跑
今天我们用 animateTo 的完成回调串两段动画。
很多动效看着乱,不是因为动画不够多,而是前一段还没结束,后一段已经抢着开始了。这个 Demo 只做两段:第一张卡片先滑出去,完成后第二张卡片再出现。
这个 Demo 看什么
核心在 startLinkage():
第一段 animateTo 修改 firstDone。等它的 onFinish 触发,再启动第二段 animateTo 修改 secondDone。
这样写的好处很直接:每段动画都有自己的起点和落点,顺序也清楚。等你以后要做更复杂的编排,再考虑抽方法或做专门的动画控制器。
如果你的页面里有“先收起、再展开”“先移动、再强调”这类动作,可以先用这种方式把顺序跑通。
完整代码
@Entry
@Component
struct ArkUIAnimationLinkageDemo {
@State firstDone: boolean = false;
@State secondDone: boolean = false;
@State runningText: string = '等待开始';
private startLinkage(): void {
this.runningText = '第一段:卡片先滑出去';
this.getUIContext().animateTo({
duration: 420,
curve: Curve.EaseInOut,
onFinish: () => {
this.runningText = '第二段:强调状态再出现';
this.getUIContext().animateTo({
duration: 360,
curve: Curve.EaseOut,
onFinish: () => {
this.runningText = '两段动画已经顺序完成';
}
}, () => {
this.secondDone = true;
})
}
}, () => {
this.firstDone = true;
})
}
private resetLinkage(): void {
this.getUIContext().animateTo({ duration: 260, curve: Curve.EaseInOut }, () => {
this.firstDone = false;
this.secondDone = false;
this.runningText = '等待开始';
})
}
@Builder
HeaderBlock() {
Column({ space: 8 }) {
Text('ArkUI 动画衔接')
.fontSize(28)
.fontWeight(700)
.fontColor('#111827')
Text('一个动作结束,下一个别抢跑')
.fontSize(16)
.fontColor('#4B5563')
Text('这页只看一件事:第一段 animateTo 完成以后,再在 onFinish 里启动第二段。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
build() {
Scroll() {
Column({ space: 22 }) {
this.HeaderBlock()
Stack({ alignContent: Alignment.Center }) {
Column({ space: 8 }) {
Text('第一段')
.fontSize(14)
.fontColor('#DBEAFE')
Text('滑动离场')
.fontSize(22)
.fontWeight(700)
.fontColor('#FFFFFF')
}
.width(150)
.height(110)
.borderRadius(20)
.justifyContent(FlexAlign.Center)
.backgroundColor('#2563EB')
.translate({ x: this.firstDone ? -92 : 0, y: this.firstDone ? -18 : 0 })
.opacity(this.firstDone ? 0.55 : 1)
Column({ space: 8 }) {
Text('第二段')
.fontSize(14)
.fontColor('#D1FAE5')
Text('强调出现')
.fontSize(22)
.fontWeight(700)
.fontColor('#FFFFFF')
}
.width(150)
.height(110)
.borderRadius(20)
.justifyContent(FlexAlign.Center)
.backgroundColor('#0F766E')
.scale({ x: this.secondDone ? 1 : 0.72, y: this.secondDone ? 1 : 0.72 })
.opacity(this.secondDone ? 1 : 0)
.translate({ x: this.secondDone ? 76 : 0, y: this.secondDone ? 26 : 0 })
}
.width('100%')
.height(220)
.borderRadius(20)
.backgroundColor('#F8FAFC')
.border({ width: 1, color: '#E5E7EB' })
Text(this.runningText)
.width('100%')
.padding(14)
.borderRadius(14)
.backgroundColor('#111827')
.fontSize(14)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
Row({ space: 12 }) {
Button('顺序播放')
.height(42)
.fontSize(14)
.fontColor('#FFFFFF')
.backgroundColor('#2563EB')
.borderRadius(21)
.layoutWeight(1)
.onClick(() => {
this.startLinkage();
})
Button('重置')
.height(42)
.fontSize(14)
.fontColor('#111827')
.backgroundColor('#E5E7EB')
.borderRadius(21)
.layoutWeight(1)
.onClick(() => {
this.resetLinkage();
})
}
.width('100%')
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)