第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 适配技巧
  • 实战:一个带轮播图的首页
相关推荐
胡gh2 小时前
依旧性能优化,如何在浅比较上做文章,memo 满天飞,谁在裸奔?
前端·react.js·面试
大怪v2 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
胡gh2 小时前
你一般用哪些状态管理库?别担心,Zustand和Redux就能说个10分钟
前端·面试·node.js
roamingcode4 小时前
Claude Code NPM 包发布命令
前端·npm·node.js·claude·自定义指令·claude code
码哥DFS4 小时前
NPM模块化总结
前端·javascript
灵感__idea4 小时前
JavaScript高级程序设计(第5版):代码整洁之道
前端·javascript·程序员
唐璜Taro4 小时前
electron进程间通信-IPC通信注册机制
前端·javascript·electron
爱笑的眼睛115 小时前
HarmonyOS TextArea 组件:文本输入区域的简单使用指南
华为·harmonyos
前端世界5 小时前
鸿蒙异步处理从入门到实战:Promise、async/await、并发池、超时重试全套攻略
华为·harmonyos
陪我一起学编程6 小时前
创建Vue项目的不同方式及项目规范化配置
前端·javascript·vue.js·git·elementui·axios·企业规范