第5章 高级UI与动画

5.1 自定义组件

在鸿蒙 ArkTS 中,你可以把 UI 和逻辑封装成可复用的组件。

📌 示例:封装一个卡片组件

bash 复制代码
@Component
struct InfoCard {
  title: string
  desc: string

  build() {
    Column({ space: 5 }) {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      Text(this.desc)
        .fontSize(16)
        .fontColor(Color.Gray)
    }
    .padding(15)
    .backgroundColor("#FFFFFF")
    .borderRadius(12)
    .shadow({ radius: 8, color: '#22000000' })
    .margin(10)
  }
}

调用方式:

bash 复制代码
InfoCard({ title: "鸿蒙教程", desc: "从入门到精通" })
InfoCard({ title: "UI开发", desc: "动画与自定义组件" })

5.2 动画效果

鸿蒙支持 属性动画(Property Animation)过渡动画(Transition Animation)

1. 属性动画

适用于 透明度、缩放、旋转、位置 的动态效果。

📌 示例:点击按钮让图片放大

bash 复制代码
@Entry
@Component
struct ScaleImage {
  @State scale: number = 1

  build() {
    Column({ alignItems: HorizontalAlign.Center, space: 20 }) {
      Image($r('app.media.logo'))
        .width(100 * this.scale)
        .height(100 * this.scale)
        .animation({
          duration: 500,
          curve: Curve.EaseInOut
        })

      Button("放大图片")
        .onClick(() => {
          this.scale = this.scale === 1 ? 1.5 : 1
        })
    }
  }
}

2. 过渡动画

适用于 组件进入/退出/切换 时的效果。

📌 示例:点击按钮切换显示文本(淡入淡出)

bash 复制代码
@Entry
@Component
struct FadeText {
  @State show: boolean = true

  build() {
    Column({ space: 20, alignItems: HorizontalAlign.Center }) {
      if (this.show) {
        Text("Hello HarmonyOS")
          .fontSize(26)
          .transition(TransitionEffect.opacity(500))
      }

      Button("切换文字")
        .onClick(() => {
          this.show = !this.show
        })
    }
  }
}

3. 动画曲线

鸿蒙提供多种动画曲线(Curve):

  • Linear(匀速)
  • EaseIn(慢 → 快)
  • EaseOut(快 → 慢)
  • EaseInOut(慢 → 快 → 慢)
  • Spring(弹簧效果)

📌 示例:弹簧动画

bash 复制代码
Text("弹簧动画")
  .translate({ x: 100 })
  .animation({
    duration: 800,
    curve: Curve.Spring
  })

5.3 UI优化与多终端适配

鸿蒙支持一次开发,多端适配。

常用技巧:

  • 使用 percentage(百分比)控制宽高,避免固定像素。
  • 使用 FlexColumnRow 进行自适应布局。
  • 根据设备类型调整样式:
bash 复制代码
if (getContext().deviceInfo.deviceType === 'tablet') {
  // 平板样式
} else {
  // 手机样式
}

5.4 实操:实现一个首页轮播图

功能需求

  • 首页展示多张图片
  • 图片自动切换
  • 用户也可以手动滑动

代码:index.ets

bash 复制代码
@Entry
@Component
struct CarouselDemo {
  private images: Resource[] = [
    $r('app.media.banner1'),
    $r('app.media.banner2'),
    $r('app.media.banner3')
  ]
  @State currentIndex: number = 0

  aboutToAppear() {
    setInterval(() => {
      this.currentIndex = (this.currentIndex + 1) % this.images.length
    }, 3000) // 3秒切换一次
  }

  build() {
    Column({ alignItems: HorizontalAlign.Center }) {
      // 图片轮播
      Swiper({ index: this.currentIndex, autoPlay: true, interval: 3000 }) {
        ForEach(this.images, (item: Resource, index: number) => {
          Image(item)
            .width('90%')
            .height(200)
            .borderRadius(12)
        })
      }

      // 底部小圆点
      Row({ space: 8, justifyContent: FlexAlign.Center }) {
        ForEach(this.images, (item: Resource, index: number) => {
          Circle({ radius: 6 })
            .fill(this.currentIndex === index ? Color.Blue : Color.Gray)
        })
      }
      .margin({ top: 10 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

运行效果

  • 首页显示 3 张图片(需放到 resources/base/media/ 下:banner1.pngbanner2.pngbanner3.png)。
  • 自动每 3 秒切换,也支持手动左右滑动。
  • 底部小圆点实时显示当前页。

✅ 到这里,你已经掌握了:

  • 自定义组件封装
  • 属性动画 & 过渡动画
  • 动画曲线的使用
  • UI 适配技巧
  • 实战:一个带轮播图的首页
相关推荐
why技术1 小时前
eli5,我觉得这个全网在吹的技能,使用体验真的很一般啊。
前端·人工智能·后端
excel1 小时前
记录升级 nuxt3 到 nuxt4 记录
前端
mmsx1 小时前
基于 Android 的博物馆文化展示与预约 App —— 设计与实现(有源码和文档)
android·app·源码·文档
剑胆琴心静水深流2 小时前
全栈之路6---web集成与呈现
前端·vue.js·spring boot·分布式·spring·前端框架·npm
前端snow2 小时前
ai agent -- Memory汇总
前端
ITresearchGuest2 小时前
AI 焦虑下,前端该何去何从
前端·人工智能
Codiggerworld3 小时前
Chrome DevTools 隐藏神技:这 5 个调试技巧你可能从来没用过
前端·chrome·chrome devtools
旋生万物3 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf
IT_陈寒3 小时前
被Java的final坑惨了,这些细节你可能也忽略了
前端·人工智能·后端
kyriewen3 小时前
我带着DeepSeek Harness跑了一周真实需求——这份避坑速查表请收好
前端·ai编程·deepseek