HarmonyOS 鸿蒙Next中为什么我的animateTo动画不执行?
HarmonyOS 鸿蒙Next中为什么我的animateTo动画不执行? 我希望在页面刚显示的时候给pagview加个从屏幕底部滑出的动画,但这个动画怎么都不执行,我还写了个demo,demo是正常的,就我的不执行,求助大佬。
代码:
import { PAGView } from "[@tencent](/user/tencent)/libpag";
import * as pag from '[@tencent](/user/tencent)/libpag';
import { AppUtil, DisplayUtil, NetworkUtil } from "[@pura](/user/pura)/harmony-utils";
import { Logger } from "utils";
import curves from "[@ohos](/user/ohos).curves";
import { fetchSleepData, SleepViewModel } from "../viewmodel/SleepViewModel";
const CENTER_PAG_VIEW_WIDTH = 200;
const CENTER_PAG_VIEW_HEIGHT = 200;
const FLOAT_DISTANCE = 6;
const SCREEN_HEIGHT = AppUtil.getUIContext().px2vp(DisplayUtil.getHeight())
const TAG='SleepView'
const STATUS_BAR_HEIGHT= AppUtil.getUIContext().px2vp(AppUtil.getStatusBarHeight())
[@ComponentV2](/user/ComponentV2)
export struct SleepView {
viewModel: SleepViewModel = SleepViewModel.getInstance();
bubbleCount=0;
[@Local](/user/Local) centerPagViewController: pag.PAGViewController = new pag.PAGViewController();
[@Local](/user/Local) leftPagViewController: pag.PAGViewController = new pag.PAGViewController();
[@Local](/user/Local) rightPagViewController: pag.PAGViewController = new pag.PAGViewController();
[@Local](/user/Local) topPagViewController: pag.PAGViewController = new pag.PAGViewController();
// "你好"和打招呼语
[@Local](/user/Local) helloDayTranslateY:number=DisplayUtil.getHeight() - 100//100 是随便设的 ;
[@Local](/user/Local) helloDayOpacity:number=0;
[@Local](/user/Local) helloDayScaleX: number=0;
[@Local](/user/Local) helloDayScaleY: number =0;
[@Local](/user/Local) dayTextOpacity:number=0;
// 刷新时间
[@Local](/user/Local) refreshTimeOpacity:number=1;
// 左下角气泡
[@Local](/user/Local) leftBubbleTranslateX:number=DisplayUtil.getWidth() / 2;
[@Local](/user/Local) leftBubbleTranslateY:number=(DisplayUtil.getHeight() - 100)/2;//100 是随便设的 ;
[@Local](/user/Local) leftBubbleScaleX:number=0;
[@Local](/user/Local) leftBubbleScaleY:number=0;
// 右下角动画
[@Local](/user/Local) rightBubbleTranslateX:number=DisplayUtil.getWidth() / 2;
[@Local](/user/Local) rightBubbleTranslateY:number=(DisplayUtil.getHeight() - 100)/2;//100 是随便设的 ;
[@Local](/user/Local) rightBubbleScaleX:number=0;
[@Local](/user/Local) rightBubbleScaleY:number=0;
// 右上角动画
[@Local](/user/Local) topBubbleTranslateX:number= -100;
[@Local](/user/Local) topBubbleTranslateY:number=(200 - 100)/2;//200是小舒动画高度 ;
[@Local](/user/Local) topBubbleScaleX:number=0;
[@Local](/user/Local) topBubbleScaleY:number=0;
// 左上角小气泡
[@Local](/user/Local) bubble1TranslateX:number=0;
[@Local](/user/Local) bubble1TranslateY:number=0;//200 是中央小舒动画的高度 ;
[@Local](/user/Local) bubble1ScaleX:number=0;
[@Local](/user/Local) bubble1ScaleY:number=0;
// 右下角小气泡
[@Local](/user/Local) bubble2TranslateX:number=DisplayUtil.getWidth() / 2;
[@Local](/user/Local) bubble2TranslateY:number=200*0.1;//200 是中央小舒动画的高度 ;
[@Local](/user/Local) bubble2ScaleX:number=0;
[@Local](/user/Local) bubble2ScaleY:number=0;
// 绑定两人时右下角无内容气泡
[@Local](/user/Local) bubble3TranslateY:number=0;
[@Local](/user/Local) waitContentOpacity:number=1;
// 中央小舒动画
[@Local](/user/Local) centerPagViewOpacity:number=1;
[@Local](/user/Local) centerPagViewScaleX:number=0;
[@Local](/user/Local) centerPagViewScaleY:number=0;
[@Local](/user/Local) centerPagViewTranslateX:number=0;
[@Local](/user/Local) centerPagViewTranslateY:number=0;
// 整个下半部分
[@Local](/user/Local) moreVisibility: Visibility = Visibility.Hidden;
[@Local](/user/Local) moreTranslateY:number=0;
// 背景光点图片
[@Local](/user/Local) bgImageOpacity:number=1;
[@Local](/user/Local) bgImageTranslateY:number=0;
[@Local](/user/Local) bgImageTranslateX:number=0;
bgImageWidth:number=0;
bgImageHeight:number=0;
// 对话文案和引导
[@Local](/user/Local) conversationContentTranslateY: number=0;
private async showWaitView() {
let centerPagFile = AppUtil.getContext().resourceDir + "/AISoftide.pag";
let file = await pag.PAGFile.LoadFromPathAsync(centerPagFile)
this.centerPagViewController.setComposition(file);
this.centerPagViewController.setRepeatCount(0);
this.centerPagViewController.play();
let leftWaitPagFile = AppUtil.getContext().resourceDir + "/loading.pag";
let leftFile = await pag.PAGFile.LoadFromPathAsync(leftWaitPagFile)
this.leftPagViewController.setComposition(leftFile);
this.leftPagViewController.setRepeatCount(0);
this.leftPagViewController.play();
let rightWaitPagFile = AppUtil.getContext().resourceDir + "/loading.pag";
let rightFile = await pag.PAGFile.LoadFromPathAsync(rightWaitPagFile)
this.rightPagViewController.setComposition(rightFile);
this.rightPagViewController.setRepeatCount(0);
this.rightPagViewController.play();
let topWaitPagFile = AppUtil.getContext().resourceDir + "/loading.pag";
let topFile = await pag.PAGFile.LoadFromPathAsync(topWaitPagFile)
this.topPagViewController.setComposition(topFile);
this.topPagViewController.setRepeatCount(0);
this.topPagViewController.play();
// this.refreshLoading();
// this.startWaitAnimateView();
if (NetworkUtil.isNetworkAvailable()){
// if (DateUtils.isTodayFirstEnter()) { // 首次进入
if (true){
// if (this.hasBindBed()) {
if (true) {
this.hasBedFirstEnter()
} else {
// this.noBedFirstEnter()
}
}else { // 非首次进入
// if (this.hasBindBed()) {
// this.hasBedEnter()
// } else {
// this.noBedEnter()
// }
}
}else{
// this.showNoNetConnectView();
}
}
// 当天首次进入
private hasBedFirstEnter(){
this.setPvAnimator() // PAG动画 (AI圆形动画)
this.setDayAndHelloAnimator() // 日期和问候语动画
this.setTimeAnimator() // 时间动画
this.setLeftBubble() // 左侧气泡设置
this.setRightBubble() // 右侧气泡设置
this.setTopBubble() // 顶部气泡设置
this.setBubble1Animator() // 气泡1动画
this.setBubble2Animator() // 气泡2动画
}
// 气泡扩散+底部弹出
private startWaitAnimateView(){
// 小舒底部弹出
this.setPvAnimator()
// 打招呼语底部弹出
this.setDayAndHelloAnimator();
// 刷新时间渐显
this.setTimeAnimator()
// 气泡扩散
this.setLeftBubble();
this.setRightBubble();
this.setTopBubble();
this.setBubble1Animator();
this.setBubble2Animator();
// 气泡漂浮
this.setFloatAnimator();
// 等候语渐显
this.setShowNextAnimator();
}
private setPvAnimator(){
// 小舒动画底部弹出
this.centerPagViewTranslateY = SCREEN_HEIGHT - CENTER_PAG_VIEW_HEIGHT;
// 修复animateTo与V2的刷新机制不兼容
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration:1500,
curve:curves.springMotion()
},()=>{
this.centerPagViewTranslateY = 0;
})
}
private setDayAndHelloAnimator(){
//时间与问候语动画
this.helloDayOpacity=0;
this.helloDayTranslateY=SCREEN_HEIGHT - CENTER_PAG_VIEW_HEIGHT;
this.dayTextOpacity=0;
// 修复animateTo与V2的刷新机制不兼容
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration:1500,
curve:curves.springMotion()
},()=>{
this.helloDayTranslateY=0;
})
AppUtil.getUIContext().animateTo({
duration:500,
delay:283,
curve:curves.cubicBezierCurve(0.33, 0, 0.67, 1.0)
},()=>{
this.helloDayOpacity=1;
})
AppUtil.getUIContext().animateTo({
duration:332,
delay:1667,
curve:curves.cubicBezierCurve(0.33, 0, 0.67, 1.0)
},()=>{
this.dayTextOpacity=1;
})
}
private setTimeAnimator(){
this.refreshTimeOpacity=0;
//刷新时间动画
setTimeout( ()=>{
AppUtil.getUIContext().animateTo({
duration:167,
delay:1500,
curve:Curve.Linear
},()=>{
this.refreshTimeOpacity=1;
})
},1)
}
private setLeftBubble(){
//左下角气泡动画
this.leftBubbleScaleX=0.2;
this.leftBubbleScaleY=0.2;
this.leftBubbleTranslateX=50;
this.leftBubbleTranslateY=-45;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
delay: 1500
},()=>{
this.leftBubbleTranslateX=1;
this.leftBubbleTranslateY=1;
this.leftBubbleScaleX=1;
this.leftBubbleScaleY=1;
})
}
private setRightBubble(){
if (this.bubbleCount===2){
}else{
//右下角气泡动画
this.rightBubbleScaleX=0.2;
this.rightBubbleScaleY=0.2;
this.rightBubbleTranslateX=-(CENTER_PAG_VIEW_WIDTH)/2;
this.rightBubbleTranslateY=-(CENTER_PAG_VIEW_HEIGHT-32)/2;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
delay: 1500
},()=>{
this.rightBubbleTranslateX=1;
this.rightBubbleTranslateY=1;
this.rightBubbleScaleX=1;
this.rightBubbleScaleY=1;
})
}
}
private setTopBubble(){
this.topBubbleScaleX=0.2;
this.topBubbleScaleY=0.2;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
delay: 1500
},()=>{
this.topBubbleTranslateX=0;
this.topBubbleTranslateY=0;
this.topBubbleScaleX=1;
this.topBubbleScaleY=1;
})
}
private setBubble1Animator() {
if (this.bubbleCount>3) {
}else {
this.bubble1ScaleX=0.2;
this.bubble1ScaleY=0.2;
this.bubble1TranslateX=100;
this.bubble1TranslateY=(200-32)/2//200是小舒动画高度,32是bubble1高度;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
delay: 1500
},()=>{
this.bubble1TranslateX=0;
this.bubble1TranslateY=0;
this.bubble1ScaleX=1;
this.bubble1ScaleY=1;
})
}
}
private setBubble2Animator() {
if (this.bubbleCount===2) {
return
}
this.bubble2ScaleX=0.2;
this.bubble2ScaleY=0.2;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
delay: 1500
},()=>{
this.bubble2TranslateX=1;
this.bubble2TranslateY=1;
this.bubble2ScaleX=1;
this.bubble2ScaleY=1;
})
}
private setFloatAnimator(){
//浮动动画
AppUtil.getUIContext().animateTo( {
duration:2000,
delay:2500,
playMode: PlayMode.AlternateReverse,
iterations:-1,
}, () => {
this.topBubbleTranslateY=FLOAT_DISTANCE;
this.leftBubbleTranslateY=-FLOAT_DISTANCE;
this.rightBubbleTranslateY=FLOAT_DISTANCE;
})
}
private setShowNextAnimator(){
this.waitContentOpacity=0;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 300,
delay: 3625
},()=>{
this.waitContentOpacity=1;
})
}
/**
* 每次请求完数据执行这个方法
*/
private firstStep(){
this.moreVisibility=Visibility.Hidden;
this.resetBindView();
this.setNextAnimator()
}
// 重置多个组件状态
private resetBindView(){
// 重置气泡1的视图状态
this.bubble1TranslateX=0;
this.bubble1TranslateY=0;
this.bubble1ScaleX=1;
this.bubble1ScaleY=1;
// 重置气泡2的视图状态
this.bubble2TranslateX=0;
this.bubble2TranslateY=0;
this.bubble2ScaleX=1;
this.bubble2ScaleY=1;
// 重置顶部气泡布局的视图状态
this.topBubbleTranslateX=0;
this.topBubbleTranslateY=0;
this.topBubbleScaleX=1;
this.topBubbleScaleY=1;
// 重置左侧气泡布局的视图状态
this.leftBubbleTranslateX=0;
this.leftBubbleTranslateY=0;
this.leftBubbleScaleX=1;
this.leftBubbleScaleY=1;
// 重置右侧气泡布局的视图状态
this.rightBubbleTranslateX=0;
this.rightBubbleTranslateY=0;
this.rightBubbleScaleX=1;
this.rightBubbleScaleY=1;
// // 重置更多气泡的视图状态
// resetViewState(binding.ivBubbleMore)
// 重置页面视图容器的视图状态
// resetViewState(binding.clPagview)
// resetViewState(binding.clContent)
// // 重置摘要文本的视图状态
// resetViewState(binding.tvSummary)
// // 重置分割线的视图状态
// resetViewState(binding.vSpilt)
// // 重置建议布局的视图状态
// resetViewState(binding.llAdvice)
// // 重置更多内容布局的视图状态
// resetViewState(binding.clMore)
// // 重置展开按钮的视图状态
// resetViewState(binding.ivExpand)
// // 重置"你好的一天"布局的视图状态
// resetViewState(binding.llHelloDay)
}
private setNextAnimator(isBind:boolean=true){
if (isBind) {
this.showNextAnimator()
} else {
this.showUnBindNextAnimator()
}
}
private showNextAnimator(){
this.setNextBgAnimator()
this.setNextDayAndHelloAnimator()
this.setUpNextAnimator();
this.setNextFloatAnimator();
}
private showUnBindNextAnimator(){
this.setNextBgAnimator();
}
private setNextBgAnimator(){
//背景动画
this.bgImageTranslateY=0;
this.bgImageTranslateX=0;
this.bgImageOpacity=1;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 300,
delay: 200,
curve:curves.cubicBezierCurve(0.33, 0, 0.87, 1.0)
},()=>{
this.bgImageTranslateY=(this.bgImageHeight-DisplayUtil.getHeight())/5*3;
this.bgImageTranslateX=this.bgImageWidth/10;
this.bgImageOpacity=0.81;
})
}
private setUpAnimator() {
this.centerPagViewOpacity = 1;
this.centerPagViewTranslateY = 0;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
}, () => {
this.centerPagViewTranslateY = -70;
})
}
private setNextDayAndHelloAnimator(){
//时间与问候语动画
this.helloDayScaleX=1;
this.helloDayScaleY=1;
this.dayTextOpacity=1;
animateToImmediately({
duration: 0
}, () => {
})
AppUtil.getUIContext().animateTo({
duration: 500,
curve: curves.cubicBezierCur更多关于HarmonyOS 鸿蒙Next中为什么我的animateTo动画不执行?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【问题定位】
观察问题代码,发现在onAppear方法中存在await操作,尝试把相关代码注释掉,之后动画可以正确展示,故问题出现在await操作上。
【分析结论】 onAppear()方法中执行await操作,导致animateToImmediately无法正确执行。
【修改建议】 把await相关操作移动到aboutToAppear上,修改后代码如下:
import { AppUtil } from '@pura/harmony-utils';
import * as pag from '@tencent/libpag';
import { PAGView } from '@tencent/libpag';
import { curves } from '@kit.ArkUI';
@ComponentV2
@Entry
export struct Index2 {
@Local centerPagViewController: pag.PAGViewController = new pag.PAGViewController();
@Local centerPagViewTranslateX: number = 0;
@Local centerPagViewTranslateY: number = 0;
@Local centerPagViewOpacity: number = 1;
async aboutToAppear(): Promise<void> {
let centerPagFile = AppUtil.getContext().resourceDir + '/AISoftide.pag';
let file = await pag.PAGFile.LoadFromPathAsync(centerPagFile)
this.centerPagViewController.setComposition(file);
this.centerPagViewController.setRepeatCount(0);
this.centerPagViewController.play();
}
build() {
RelativeContainer() {
Scroll() {
RelativeContainer() {
RelativeContainer() {
PAGView({ controller: this.centerPagViewController })
.id('center_pagview')
.size({ width: 199, height: 199 })
.opacity(this.centerPagViewOpacity)
.translate({ x: this.centerPagViewTranslateX, y: this.centerPagViewTranslateY })
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.Center },
top: { anchor: '__container__', align: VerticalAlign.Top }
})
Image($r('app.media.startIcon'))
.size({ width: 34, height: 40 })
.margin({ bottom: 20 })
.alignRules({
middle: { anchor: 'center_pagview', align: HorizontalAlign.Center },
center: { anchor: 'center_pagview', align: VerticalAlign.Center }
})
}
.size({ width: 200, height: 200 })
.id('rc_center_pagview')
.margin({ top: 91 })
.translate({ x: this.centerPagViewTranslateX, y: this.centerPagViewTranslateY })
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.Center },
top: { anchor: '__container__', align: VerticalAlign.Top }
})
}.padding({ left: 16, right: 16 })
.width('100%')
.height('auto')
}
.width('100%')
.height('100%')
.alignRules({
top: { anchor: 'fake_statusBar', align: VerticalAlign.Bottom },
})
.onAppear(() => {
// 如果在aboutToAppear中调用动画,自定义组件内的build还未执行,内部组件还未创建,动画时机过早,动画属性没有初值无法对组件产生动画。
this.showWaitView()
})
}
}
async showWaitView() {
this.centerPagViewTranslateY = 600
animateToImmediately({
duration: 0,
}, () => {
AppUtil.getUIContext().animateTo({
duration: 1500,
curve: curves.springMotion()
}, () => {
this.centerPagViewTranslateY = 0;
})
})
}
}
更多关于HarmonyOS 鸿蒙Next中为什么我的animateTo动画不执行?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以在animateTo的事件中加个log看是否执行了
我简单仿写了一个动画 是可以正常执行的 我使用的
this.getUIContext().animateTo
加了,有日志,但看起来就是没动画,我也很费解,目前找到了个解决办法,就是给animateTo加个setTimeOut,就有动画了,但不理解为什么,
检查动画代码是否在UI线程执行,确保状态变量使用@State装饰器。动画参数需正确设置,duration和curve属性不能缺失。确认组件可见且未被遮挡,父容器尺寸需有效。动画触发条件需满足,避免在页面生命周期错误阶段调用。


