news 2026/4/16 13:36:24

鸿蒙技术干货11:属性动画与转场效果实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙技术干货11:属性动画与转场效果实战

本文聚焦基础属性动画(animateTo)和页面转场动画(transition),通过「列表项滑动删除 + 页面切换渐变」的实战案例,带大家掌握动画开发核心逻辑~

一、核心认知:动画的应用场景与核心 API

1. 应用场景

  • 组件交互反馈(如按钮点击缩放、列表项操作动画)
  • 页面切换过渡(如渐变、滑动进入)
  • 数据变化可视化(如进度条加载、数字滚动)
  • 引导用户注意力(如弹窗弹出、通知提示)

2. 核心 API

  • 属性动画:animateTo(声明式动画,无需手动控制动画帧)
  • 转场动画:transition(组件转场配置)、pageTransition(页面转场配置)
  • 关键参数:duration(时长)、curve(动画曲线)、delay(延迟执行)

二、属性动画:animateTo 基础用法

属性动画通过animateTo函数包裹组件属性修改逻辑,自动实现动画过渡,支持位置、透明度、尺寸等常见属性:

1. 基础效果示例(控制透明度、尺寸、位置)

import { animateTo, Curve } from '@ohos.ui.animation'; @Component struct AnimateToBasicDemo { @State opacity: number = 1; @State scale: number = 1; @State offsetX: number = 0; build() { Column({ space: 30 }) .width('100%') .height('100%') .padding(30) .backgroundColor('#f5f5f5') { // 动画目标组件 Text('属性动画演示') .fontSize(24) .fontWeight(FontWeight.Bold) .opacity(this.opacity) .scale({ x: this.scale, y: this.scale }) .translate({ x: this.offsetX }) .backgroundColor('#2f54eb') .color('#ffffff') .padding(20) .borderRadius(12) // 控制按钮组 Row({ space: 20 }) { Button('透明度变化') .type(ButtonType.Capsule) .onClick(() => { animateTo({ duration: 800, // 动画时长(毫秒) curve: Curve.EaseInOut // 动画曲线(缓进缓出) }, () => { this.opacity = this.opacity === 1 ? 0.3 : 1; }); }) Button('缩放效果') .type(ButtonType.Capsule) .onClick(() => { animateTo({ duration: 500 }, () => { this.scale = this.scale === 1 ? 1.2 : 1; }); }) Button('水平位移') .type(ButtonType.Capsule) .onClick(() => { animateTo({ duration: 1000 }, () => { this.offsetX = this.offsetX === 0 ? 100 : 0; }); }) } } } }

2. 核心参数说明

  • duration:动画时长(默认 300 毫秒),数值越大动画越慢;
  • curve:动画曲线(Curve.Linear匀速、Curve.EaseIn缓入、Curve.EaseOut缓出、Curve.EaseInOut缓进缓出);
  • delay:延迟执行时间(默认 0 毫秒),可实现动画排队效果;
  • 回调函数:包裹需要动画的属性修改逻辑,属性变化会自动生成过渡动画。

三、转场动画:transition 组件用法

转场动画用于组件显示 / 隐藏、页面切换时的过渡效果,鸿蒙 5.0 + 支持通过transition直接配置,无需复杂逻辑:

1. 页面切换渐变效果

main_pages.json注册的页面中,通过pageTransition配置全局页面转场:

// pages/FirstPage.ets(首页) @Entry @Component struct FirstPage { build() { Column({ space: 30 }) .width('100%') .height('100%') .padding(30) .backgroundColor('#f5f5f5') { Text('首页') .fontSize(32) .fontWeight(FontWeight.Bold) Button('跳转到第二页') .type(ButtonType.Capsule) .width(200) .height(50) .backgroundColor('#2f54eb') .onClick(() => { router.pushUrl({ url: 'pages/SecondPage' }); }) } } // 页面转场配置(渐变效果) pageTransition() { PageTransition() .enter('fade', { duration: 800, curve: Curve.EaseInOut }) // 进入渐变 .exit('fade', { duration: 800, curve: Curve.EaseInOut }) // 退出渐变 } } // pages/SecondPage.ets(第二页) @Entry @Component struct SecondPage { build() { Column({ space: 30 }) .width('100%') .height('100%') .padding(30) .backgroundColor('#f5f5f5') { Text('第二页') .fontSize(32) .fontWeight(FontWeight.Bold) Button('返回首页') .type(ButtonType.Capsule) .width(200) .height(50) .backgroundColor('#ff4d4f') .onClick(() => { router.backUrl(); }) } } // 复用渐变转场配置 pageTransition() { PageTransition() .enter('fade', { duration: 800, curve: Curve.EaseInOut }) .exit('fade', { duration: 800, curve: Curve.EaseInOut }) } }

2. 组件转场(列表项滑动删除前置)

组件显示 / 隐藏时的转场效果,可结合ifvisibility控制:

// 组件转场示例(渐变+位移) Text('可隐藏组件') .transition([ TransitionEffect.fade({ duration: 500 }), // 渐变 TransitionEffect.slide({ direction: SlideDirection.Bottom, duration: 500 }) // 底部滑入滑出 ]) .visibility(this.isShow ? Visibility.Visible : Visibility.Hidden)

四、实战整合:列表项滑动删除 + 页面渐变

1. 列表项滑动删除(属性动画核心应用)

import { animateTo, Curve } from '@ohos.ui.animation'; import router from '@ohos.router'; @Component struct SlideDeleteList { @State taskList: string[] = ['学习属性动画', '实现转场效果', '开发滑动删除', '整合页面渐变']; @State deleteOffsetX: number[] = this.taskList.map(() => 0); // 每个列表项的位移 // 滑动删除动画 handleSwipe(index: number, offsetX: number) { // 限制滑动范围(-200到0,200为删除按钮宽度) if (offsetX < -200) offsetX = -200; if (offsetX > 0) offsetX = 0; this.deleteOffsetX[index] = offsetX; } // 删除列表项(带动画) deleteItem(index: number) { animateTo({ duration: 500, curve: Curve.EaseOut }, () => { this.deleteOffsetX[index] = -this.taskList.length * 200; // 快速滑出屏幕 }, () => { this.taskList.splice(index, 1); this.deleteOffsetX.splice(index, 1); // 移除对应位移状态 }); } build() { Column({ space: 15 }) .width('100%') .padding(30) .backgroundColor('#f5f5f5') { Text('滑动删除列表') .fontSize(28) .fontWeight(FontWeight.Bold) .marginBottom(20) List({ space: 10 }) { ForEach(this.taskList, (task, index) => { ListItem() { Stack() { // 删除按钮(默认隐藏在右侧) Button('删除') .width(200) .height('100%') .backgroundColor('#ff4d4f') .alignContent(FlexAlign.Center) .position({ x: '100%', left: -200 }) // 列表项内容(可滑动) Text(task) .width('100%') .height(80) .lineHeight(80) .padding(20) .backgroundColor('#ffffff') .borderRadius(12) .translate({ x: this.deleteOffsetX[index] }) .onTouch((e) => { if (e.type === TouchType.MOVE) { // 监听滑动事件,更新位移 this.handleSwipe(index, e.touches[0].x - e.touches[0].startX); } else if (e.type === TouchType.END) { // 滑动距离不足100,回弹 if (this.deleteOffsetX[index] > -100) { animateTo({ duration: 300 }, () => { this.deleteOffsetX[index] = 0; }); } } }) } } }) } Button('跳转到详情页(渐变效果)') .type(ButtonType.Capsule) .width(250) .height(50) .backgroundColor('#2f54eb') .marginTop(30) .onClick(() => { router.pushUrl({ url: 'pages/DetailPage' }); }) } } } // 详情页(复用页面渐变转场) @Entry @Component struct DetailPage { build() { Column() .width('100%') .height('100%') .backgroundColor('#f5f5f5') .justifyContent(FlexAlign.Center) { Text('详情页') .fontSize(32) .fontWeight(FontWeight.Bold) Button('返回列表页') .type(ButtonType.Capsule) .width(200) .height(50) .backgroundColor('#ff4d4f') .marginTop(30) .onClick(() => { router.backUrl(); }) } } pageTransition() { PageTransition() .enter('fade', { duration: 800, curve: Curve.EaseInOut }) .exit('fade', { duration: 800, curve: Curve.EaseInOut }) } }

2. 核心效果说明

  • 列表项滑动:通过onTouch监听滑动事件,animateTo控制translate位移,实现滑动露出删除按钮;
  • 删除动画:点击删除后,列表项快速滑出屏幕,动画结束后移除数据;
  • 页面渐变:通过pageTransition配置fade效果,跳转和返回时均有平滑渐变过渡。

五、实战踩坑指南

1. 动画不生效

  • 确保属性是「响应式状态」:必须用@State/@Link等装饰器,普通变量修改无法触发动画;
  • 动画函数包裹正确:animateTo的回调函数内必须直接修改属性,不可嵌套异步操作;
  • 版本适配:HarmonyOS 5.0 + 支持PageTransitionfade/slide简化配置,低版本需手动配置TransitionEffect

2. 滑动删除效果异常

  • 限制滑动范围:避免滑动过度导致 UI 错乱,建议限制在删除按钮宽度范围内;
  • 状态同步:deleteOffsetX数组需与列表数据一一对应,删除数据时同步移除对应位移状态。

3. 转场效果卡顿

  • 减少动画元素:避免同时对多个复杂组件添加动画;
  • 简化动画逻辑:优先使用系统提供的fade/slide等基础效果,自定义动画避免复杂计算。

加入班级,学习鸿蒙开发

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 13:31:01

SGLang部署Qwen3-32B与Qwen2.5-VL-32B实战

SGLang部署Qwen3-32B与Qwen2.5-VL-32B实战 在大模型推理服务日益追求高并发、低延迟的今天&#xff0c;一个关键问题摆在开发者面前&#xff1a;如何让像 Qwen3-32B 这样参数高达320亿的庞然大物&#xff0c;在实际应用中依然保持流畅响应&#xff1f;更进一步&#xff0c;如果…

作者头像 李华
网站建设 2026/4/16 13:33:45

11、小型办公室/家庭办公室网络搭建指南

小型办公室/家庭办公室网络搭建指南 1. Linux 作为网络选择的优势 Linux 通常是网络搭建的不错选择,如今许多运行在 UNIX 操作系统家族成员(如 Linux)上的网络就证明了这一点。对于小型办公室网络而言,Linux 更是特别合适。它相较于大型 UNIX 系统,体积更小、更友好,操…

作者头像 李华
网站建设 2026/4/14 13:10:26

13、KLyX文档处理全攻略

KLyX文档处理全攻略 1. KLyX简介 KLyX是一款可用于Linux - Mandrake系统的文字处理软件。它适用于多种类型的文档,无论是短文档(如备忘录、信件),还是长文档(包含页码、目录、交叉引用、图片和表格等元素)。与其他文字处理程序不同,KLyX更像是专业的排版系统,它利用文…

作者头像 李华
网站建设 2026/4/16 13:31:49

工业自动化中的FTDI串口驱动应用全解析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个工业级FTDI串口通讯监控工具&#xff0c;功能包括&#xff1a;1.实时显示串口数据流 2.支持Modbus协议解析 3.数据记录和导出CSV 4.通讯异常报警 5.波特率自动检测 6.支持多…

作者头像 李华
网站建设 2026/4/15 18:34:26

3分钟搭建MySQL数据重置原型系统

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个测试数据管理工具原型&#xff1a;1) 基于Flask的Web界面 2) 可配置多表TRUNCATE规则 3) 预设数据自动填充 4) 定时任务支持 5) 简易权限管理。要求使用PythonMySQL实现&am…

作者头像 李华
网站建设 2026/4/16 10:19:10

比apt快10倍!Ubuntu极速安装Python的3种黑科技

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建性能对比测试脚本&#xff1a;1. 用time命令统计apt安装python3.10耗时 2. 使用miniforge安装同版本耗时 3. 源码编译安装耗时。要求输出包含磁盘IO、CPU占用等监控数据的对比表…

作者头像 李华