点击点赞按钮，动画播放完毕后点赞图标消失
====================

#### 问题信息

打开页面，正常显示点赞按钮，再点击按钮，播放完点赞动画后，点赞图片消失。

#### 背景知识

*   [if/else条件渲染](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-ifelse)：条件渲染可根据应用状态，使用if、else和else if渲染相应的UI内容。
*   [setTimeout定时器](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-timer#settimeout)：设置一个定时器，该定时器在定时器到期后执行一个函数。

#### 问题定位

1.  使用DevEco Testing的UIViewer工具分别检查点赞按钮正常显示时和消失时的UI结构。确认点赞图标是Image组件，在点赞动画播放完毕后页面上没有Image组件。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/17/v3/i-DesQy6Rm-EhSFCYVmOJg/zh-cn_image_0000002628559542.png?HW-CC-KV=V1&HW-CC-Date=20260709T134024Z&HW-CC-Expire=86400&HW-CC-Sign=217640450B92629370972A90CC15EB1ED46D54A4CA69C986936C67000A363CD3 "点击放大")
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/2a/v3/uBosGV4GTdmQ105sqmmlvA/zh-cn_image_0000002658918853.png?HW-CC-KV=V1&HW-CC-Date=20260709T134024Z&HW-CC-Expire=86400&HW-CC-Sign=BBFD093357317D83A41408FAB7560E142F5C9C325A84032105883A1F0CA47D65 "点击放大")
    
2.  排查代码中点赞图片的显隐逻辑。点赞图片使用的Image组件通过if/else条件渲染，当变量满足条件时才会正常显示，点赞/取消点赞动画播放完毕后并未修改变量的值，Image组件没有正常渲染。
    
    @Entry
    @Component
    struct ErrorCode {
      @State isLike: boolean = false; _// 点赞状态_
      @State clickLikeStatus: boolean | undefined = undefined; _// 根据布尔值判断使用取消点赞/点赞动画_
      _// 点赞图片，请使用尺寸较小的本地图片_
      likeIcon: ResourceStr = $r('app.media.ic\_public\_thumbs\_up');
     _ // 未点赞时的颜色(灰色)_
      unlikeColor: string = '#757575';
      _// 点赞后的颜色(蓝色)_
      likeColor: string = '#4eabe6';
    
      build() {
        Column() {
          Row() {
            Stack() {
              if (this.clickLikeStatus === undefined) {
                Image(this.likeIcon)
                  .objectFit(ImageFit.Contain) _// 缩放填充_
                  .aspectRatio(1) _// 固定宽高比为1_
                  .width(70)
                  .syncLoad(true) _// 同步加载，避免闪烁_
                  .fillColor(this.isLike ? this.likeColor : this.unlikeColor)
              } else {
                _// 自定义组件，用于播放动画_
                LikePlayer({ isLikeAnimation: this.clickLikeStatus })
              }
            }
          }
          .onClick(() => {
            if (this.clickLikeStatus === undefined) {
              this.clickLike();
            }
          })
        }
        .justifyContent(FlexAlign.Center)
        .height('100%')
        .width('100%')
      }
    
     _ // Image组件的点击事件，可以切换播放动画和显示图片_
      clickLike() {
        if (this.isLike) {
          this.clickLikeStatus = false;
          _// 播放取消点赞动画_
        } else {
          this.clickLikeStatus = true;
         _ // 播放点赞动画_
        }
      }
    }
    
    _// 播放（取消）点赞动画，此处仅为模拟方案，实际按需替换_
    @Component
    struct LikePlayer {
      @Prop isLikeAnimation: boolean; _// 是否是点赞动画，有点赞动画和取消点赞动画_
      @State isLike: boolean = !this.isLikeAnimation; _// 当前点赞状态_
      @State scaleValue: number = 1; _// 缩放比例_
      @State showAnimation: boolean = true; _// 是否显示动画_
      _// 未点赞时的颜色(灰色)_
      unlikeColor: string = '#757575';
     _ // 点赞后的颜色(蓝色)_
      likeColor: string = '#4eabe6';
      _// 点赞图片，请使用尺寸较小的本地图片_
      likeIcon: ResourceStr = $r('app.media.ic\_public\_thumbs\_up');
    
      build() {
        Image(this.likeIcon)
          .syncLoad(true) _// 同步加载，避免闪烁_
          .objectFit(ImageFit.Contain) _// 缩放填充_
          .aspectRatio(1) _// 固定宽高比为1_
          .width(70)
          .fillColor(this.isLike ? this.likeColor : this.unlikeColor)
          .scale({ x: this.scaleValue, y: this.scaleValue }) _// 添加缩放效果_
          .onComplete(() => {
            _// 切换点赞状态_
            this.isLike = !this.isLike;
           _ // 点赞动画-第一阶段：放大_
            this.getUIContext().animateTo({
              duration: 300, _// 动画持续300毫秒_
              curve: Curve.Friction, _// 使用摩擦曲线，效果更自然_
              delay: 0 _// 无延迟立即执行_
            }, () => {
              this.scaleValue = 1.5; _// 图标放大到1.5倍_
            });
           _ // 点赞动画-第二阶段：恢复原大小_
            this.getUIContext().animateTo({
              duration: 100, _// 动画持续100毫秒_
              curve: Curve.Friction, _// 使用摩擦曲线_
              delay: 300 _// 延迟300毫秒执行，等第一阶段完成_
            }, () => {
              this.scaleValue = 1; _// 图标恢复到原始大小_
    
            });
           _ // 模拟动画播放完毕后显示空白_
            setTimeout(() => {
              this.showAnimation = false;
            }, 400);
          })
          .visibility(this.showAnimation ? Visibility.Visible : Visibility.Hidden)
      }
    }
    

#### 分析结论

点击点赞按钮时，未延时修改if/else条件渲染中使用的变量的值，在动画播放完毕后，未渲染Image组件，导致点赞图片消失。

#### 修改建议

在Image组件的点击事件中，延时修改if/else条件渲染中所使用的变量的值，保证点赞图片在动画播放完毕后正常渲染。

@Entry
@Component
struct ClickLikeBtn {
  @State isLike: boolean = false; _// 点赞状态_
  @State clickLikeStatus: boolean | undefined = undefined; _// 根据布尔值判断使用取消点赞/点赞动画_
 _ // 点赞图片，请使用尺寸较小的本地图片_
  likeIcon: ResourceStr = $r('app.media.ic\_public\_thumbs\_up');
  _// 未点赞时的颜色(灰色)_
  unlikeColor: string = '#666666';
  _// 点赞后的颜色(蓝色)_
  likeColor: string = '#0a59f7';

  build() {
    Column() {
      Row() {
        Stack() {
          if (this.clickLikeStatus == undefined) {
            Image(this.likeIcon)
              .objectFit(ImageFit.Contain) _// 缩放填充_
              .aspectRatio(1) _// 固定宽高比为1_
              .width(70)
              .syncLoad(true) _// 同步加载，避免闪烁_
              .fillColor(this.isLike ? this.likeColor : this.unlikeColor)
              .onAppear(() => {
                console.info('\[LikeIcon\]', 'appear');
              })
              .onDisAppear(() => {
                console.info('\[LikeIcon\]', 'disappear');
              });
          } else {
           _ // 自定义组件，用于播放动画_
            AnimationPlayer({ isLikeAnimation: this.clickLikeStatus });
          }
        };
      }
      .onClick(() => {
        if (this.clickLikeStatus === undefined) {
          this.clickLike();
        }
      });
    }
    .justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%');
  }

  _// Image组件的点击事件，可以切换播放动画和显示图片_
  clickLike() {
    if (this.isLike) {
      this.clickLikeStatus = false;
      _// 播放取消点赞动画_
    } else {
      this.clickLikeStatus = true;
     _ // 播放点赞动画_
    }
   _ // 使用计时器，延时修改（在动画播放完毕后修改）变量的值为undefined，渲染图片_
    _// 第二参数是点赞/取消点赞动画的时长_
    setTimeout(() => {
      this.isLike = !this.isLike;
      this.clickLikeStatus = undefined;
    }, 400);
  }
}

_// 播放（取消）点赞动画，此处仅为模拟方案，实际按需替换_
@Component
struct AnimationPlayer {
  @Prop isLikeAnimation: boolean; _// 是否是点赞动画，有点赞动画和取消点赞动画_
  @State isLike: boolean = !this.isLikeAnimation; _// 当前点赞状态_
  @State scaleValue: number = 1; _// 缩放比例_
 _ // 未点赞时的颜色(灰色)_
  unlikeColor: string = '#666666';
  _// 点赞后的颜色(蓝色)_
  likeColor: string = '#0a59f7';
  _// 点赞图片，请使用尺寸较小的本地图片_
  likeIcon: ResourceStr = $r('app.media.ic\_public\_thumbs\_up');

  build() {
    Image(this.likeIcon)
      .syncLoad(true) _// 同步加载，避免闪烁_
      .objectFit(ImageFit.Contain) _// 缩放填充_
      .aspectRatio(1) _// 固定宽高比为1_
      .width(70)
      .fillColor(this.isLike ? this.likeColor : this.unlikeColor)
      .scale({ x: this.scaleValue, y: this.scaleValue }) _// 添加缩放效果_
      .onComplete(() => {
       _ // 切换点赞状态_
        this.isLike = !this.isLike;
       _ // 点赞动画-第一阶段：放大_
        this.getUIContext().animateTo({
          duration: 300, _// 动画持续300毫秒_
          curve: Curve.Friction, _// 使用摩擦曲线，效果更自然_
          delay: 0 _// 无延迟立即执行_
        }, () => {
          this.scaleValue = 1.5; _// 图标放大到1.5倍_
        });
       _ // 点赞动画-第二阶段：恢复原大小_
        this.getUIContext().animateTo({
          duration: 100, _// 动画持续100毫秒_
          curve: Curve.Friction, _// 使用摩擦曲线_
          delay: 300 _// 延迟300毫秒执行，等第一阶段完成_
        }, () => {
          this.scaleValue = 1; _// 图标恢复到原始大小_
        });
      });
  }
}