ArkUI 动画概述:页面会动之前,先分清谁在动

举报
蓝瘦的蜕变 发表于 2026/10/25 22:33:57 2026/10/25
【摘要】 今天我们先不急着堆动效,而是把 ArkUI 里常见的动画类型摆在一起看清楚。 动画最容易写乱的地方,不是 API 多,而是还没想清楚“到底是谁在动”:是一个属性在变,还是组件在出现消失,还是页面在切换,或者只是想做一点氛围。这个 Demo 就是一个选型页,帮我们先把边界分开。 这个 Demo 看什么 准备一个 Anim

ArkUI 动画概述:页面会动之前,先分清谁在动

今天我们先不急着堆动效,而是把 ArkUI 里常见的动画类型摆在一起看清楚。

动画最容易写乱的地方,不是 API 多,而是还没想清楚“到底是谁在动”:是一个属性在变,还是组件在出现消失,还是页面在切换,或者只是想做一点氛围。这个 Demo 就是一个选型页,帮我们先把边界分开。

这个 Demo 看什么

准备一个 AnimationOverviewItem 类,把动画类型、适用场景、使用提醒和颜色收在一起。页面里用 ForEach 渲染成卡片,这样读起来像一张小抄。

这里没有复杂交互,因为总览页的重点不是“马上动起来”,而是先知道该用哪类能力:

  • 属性动画:状态变化后,让尺寸、位置、透明度顺滑过渡。
  • 显式动画:用 animateTo 明确包住一次状态修改。
  • 转场动画:处理组件出现、消失和页面切换。
  • 粒子动画:用轻量点位做氛围。
  • 帧动画:播放提前准备好的一组图片帧。

你后面写动画时,可以先问自己一句:我现在要解决的是属性变化、组件进出、页面切换,还是视觉氛围?这个问题一清楚,API 选择就不会乱。

下一篇想继续看哪个方向?是更偏“页面手感”的曲线,还是更偏“视觉氛围”的粒子?你可以按自己的项目场景挑一个。

完整代码

class AnimationOverviewItem {
  title: string;
  scene: string;
  note: string;
  color: string;

  constructor(title: string, scene: string, note: string, color: string) {
    this.title = title;
    this.scene = scene;
    this.note = note;
    this.color = color;
  }
}

@Entry
@Component
struct ArkUIAnimationOverviewDemo {
  private items: AnimationOverviewItem[] = [
    new AnimationOverviewItem('属性动画', '状态改变后,让尺寸、位置、透明度这些属性顺滑过渡。', '适合卡片展开、按钮强调、模块轻微位移。', '#2563EB'),
    new AnimationOverviewItem('显式动画', '把一次状态修改放进 animateTo 里,明确这次变化怎么动。', '适合点击后的一段明确反馈。', '#0F766E'),
    new AnimationOverviewItem('转场动画', '组件出现、消失,或者页面切换时,不要突然闪出来。', '适合列表项插入、浮层露出、页面进出。', '#B45309'),
    new AnimationOverviewItem('粒子动画', '用很多轻量点位制造氛围,不靠一张大图硬撑。', '适合庆祝、提示、背景点缀。', '#9333EA'),
    new AnimationOverviewItem('帧动画', '准备多帧图片,一帧一帧播放。', '适合小插画、表情、明确的连续动作。', '#DC2626')
  ];

  @Builder
  HeaderBlock() {
    Column({ space: 8 }) {
      Text('ArkUI 动画概述')
        .fontSize(28)
        .fontWeight(700)
        .fontColor('#111827')
      Text('页面会动之前,先分清谁在动')
        .fontSize(16)
        .fontColor('#4B5563')
      Text('这一页不急着写复杂效果,我们先把常见动画放在一张图里看清楚:属性在动、组件在进出、页面在切换,还是用粒子和帧图做氛围。')
        .fontSize(14)
        .fontColor('#6B7280')
        .lineHeight(22)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  OverviewCard(item: AnimationOverviewItem) {
    Row({ space: 14 }) {
      Text('')
        .width(6)
        .height(72)
        .borderRadius(3)
        .backgroundColor(item.color)

      Column({ space: 8 }) {
        Text(item.title)
          .fontSize(18)
          .fontWeight(700)
          .fontColor('#111827')
        Text(item.scene)
          .fontSize(14)
          .fontColor('#374151')
          .lineHeight(21)
        Text(item.note)
          .fontSize(12)
          .fontColor('#6B7280')
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .padding(16)
    .borderRadius(16)
    .backgroundColor('#FFFFFF')
    .border({ width: 1, color: '#E5E7EB' })
  }

  build() {
    Scroll() {
      Column({ space: 20 }) {
        this.HeaderBlock()

        Column({ space: 12 }) {
          ForEach(this.items, (item: AnimationOverviewItem) => {
            this.OverviewCard(item)
          }, (item: AnimationOverviewItem) => item.title)
        }
        .width('100%')

        Column({ space: 8 }) {
          Text('我们先这样选')
            .fontSize(18)
            .fontWeight(700)
            .fontColor('#111827')
          Text('只是属性变化,先用 animation 或 animateTo;需要出现和消失,再看 transition;想做氛围点缀再用 Particle;已经有连续图片素材,才考虑 ImageAnimator。')
            .fontSize(14)
            .fontColor('#4B5563')
            .lineHeight(22)
        }
        .width('100%')
        .padding(16)
        .borderRadius(16)
        .backgroundColor('#F8FAFC')
        .border({ width: 1, color: '#E5E7EB' })
        .alignItems(HorizontalAlign.Start)
      }
      .width('100%')
      .padding(24)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。