《雷达扫描动画》一、组件内转场(transition)使用指南

📅 2026/7/13 11:25:54
《雷达扫描动画》一、组件内转场(transition)使用指南
HarmonyOS ArkUI 组件内转场 (transition) 使用指南效果## 前言在HarmonyOS ArkUI开发中动画是提升用户体验的重要手段。组件内转场transition是ArkUI提供的声明式动画机制专门用于处理组件出现和消失时的过渡效果。当组件通过条件渲染if/ForEach等插入或删除时transition属性可以自动为这些变化添加平滑的动画效果。本文将从基础概念出发通过一个完整的实战示例带你全面掌握transition的使用方法。一、核心概念1.1 什么是组件内转场组件内转场是指组件在插入容器或从容器中移除时自动触发的过渡动画。它与显式动画animateTo不同不需要手动设置目标状态值而是由框架在组件生命周期变化时自动驱动。典型应用场景列表项的插入和删除动画条件渲染区块的淡入淡出弹窗或提示信息的出现和消失设备发现、消息通知等场景1.2 核心APIAPI说明TransitionEffect.IDENTITY无过渡效果默认状态TransitionEffect.OPACITY透明度变化0→1出现1→0消失TransitionEffect.scale(value)缩放变化TransitionEffect.translate(value)平移变化TransitionEffect.rotate(value)旋转变化TransitionEffect.asymmetric(appear, disappear)为出现和消失指定不同的过渡效果.animation(params)配置动画参数duration、curve、delay等.combine(effect)组合多个过渡效果1.3 动画参数说明.animation({duration:500,// 动画时长毫秒curve:Curve.EaseIn,// 动画曲线delay:0,// 延迟时间毫秒iterations:1,// 播放次数playMode:PlayMode.Normal// 播放模式})二、基础用法详解2.1 最简单的淡入淡出ComponentV2struct FadeDemo{LocalisVisible:booleanfalse;build(){Column(){Button(切换显示).onClick((){this.isVisible!this.isVisible;})if(this.isVisible){Text(Hello Transition!).fontSize(20).padding(20)// 使用默认OPACITY效果出现时透明度从0渐变到1消失时从1渐变到0.transition(TransitionEffect.OPACITY)}}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}2.2 添加自定义动画参数Text(Hello Transition!).fontSize(20).transition(TransitionEffect.OPACITY.animation({duration:800,curve:Curve.EaseInOut}))2.3 组合多种效果Text(组合效果).transition(TransitionEffect.OPACITY.animation({duration:600,curve:Curve.EaseOut}).combine(TransitionEffect.scale({x:0.5,y:0.5})).combine(TransitionEffect.translate({y:-50})))效果说明组件出现时同时执行透明度渐变、从50%放大到100%、从上方50px处滑入三个动画。2.4 非对称转场appear和disappear使用不同效果Text(非对称转场).transition(TransitionEffect.asymmetric(// 出现时从左侧滑入 透明度渐变TransitionEffect.OPACITY.animation({duration:500,curve:Curve.EaseOut}).combine(TransitionEffect.translate({x:-100})),// 消失时直接消失无过渡TransitionEffect.IDENTITY))asymmetric方法接收两个参数第一个参数组件出现时的过渡效果第二个参数组件消失时的过渡效果三、实战示例消息通知列表下面通过一个消息通知列表的实战示例综合运用transition的各种效果。3.1 数据模型ObservedV2classNotificationItem{Traceid:number0;Tracetitle:string;Tracecontent:string;Tracetime:string;}3.2 完整页面代码EntryComponentV2struct TransitionDemo{Localnotifications:NotificationItem[][];LocalnextId:number1;// 添加通知addNotification():void{constitemnewNotificationItem();item.idthis.nextId;item.title新消息 #${item.id};item.content这是一条通过transition实现淡入效果的通知消息;item.timenewDate().toLocaleTimeString();// 插入到列表头部this.notifications.unshift(item);}// 删除通知removeNotification(index:number):void{this.notifications.splice(index,1);}BuildernotificationCard(item:NotificationItem,index:number){Row(){Column(){Text(item.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#182431)Text(item.content).fontSize(13).fontColor(#99182431).margin({top:4}).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})Text(item.time).fontSize(11).fontColor(#66182431).margin({top:6})}.layoutWeight(1)Button(删除).fontSize(12).type(ButtonType.Capsule).backgroundColor(#FF4444).onClick((){this.removeNotification(index);})}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(12).shadow({radius:4,color:#1A000000,offsetY:2})// 非对称转场出现时从左侧滑入透明度消失时缩小透明度.transition(TransitionEffect.asymmetric(TransitionEffect.OPACITY.animation({duration:400,curve:Curve.EaseOut}).combine(TransitionEffect.translate({x:-60})),TransitionEffect.OPACITY.animation({duration:300,curve:Curve.EaseIn}).combine(TransitionEffect.scale({x:0.8,y:0.8}))))}build(){Column(){// 标题Text(Transition 消息通知示例).fontSize(20).fontWeight(FontWeight.Bold).margin({top:20,bottom:16})// 操作按钮Button(添加通知).width(160).height(40).fontSize(16).backgroundColor(#007DFF).type(ButtonType.Capsule).onClick((){this.addNotification();})// 通知列表List({space:10}){ForEach(this.notifications,(item:NotificationItem,index:number){ListItem(){this.notificationCard(item,index)}},(item:NotificationItem)item.id.toString())// 必须提供keyGenerator}.width(100%).layoutWeight(1).padding({left:16,right:16,top:16}).scrollBar(BarState.Off)}.width(100%).height(100%).backgroundColor(#F1F3F5).alignItems(HorizontalAlign.Center)}}3.3 效果说明操作动画效果点击添加通知新消息从左侧滑入同时透明度从0渐变到1点击删除消息缩小到80%并淡出四、进阶技巧4.1 缩放波纹效果雷达扫描常用BuilderrippleEffect(){Circle().width(80).height(80).fill(#007DFF).opacity(0.4)// 出现时无效果消失时放大并淡出.transition(TransitionEffect.asymmetric(TransitionEffect.IDENTITY,TransitionEffect.OPACITY.animation({duration:2500,curve:Curve.EaseOut}).combine(TransitionEffect.scale({x:3.5,y:3.5}))))}配合setInterval周期性切换布尔值实现连续波纹扩散效果startRipple():void{this.rippleFlag!this.rippleFlag;// 触发首次出现this.rippleTimerIdsetInterval((){this.rippleFlag!this.rippleFlag;// 周期性触发消失→出现},2500);}4.2 列表项错开动画通过delay参数让每个列表项的动画有先后顺序.transition(TransitionEffect.OPACITY.animation({duration:400,curve:Curve.EaseOut,delay:index*100// 每个项延迟100ms}))4.3 注意事项transition只在组件插入/移除时触发通过if条件渲染或ForEach列表增删来触发直接修改组件属性不会触发transition。配合条件渲染使用transition必须放在可能被条件渲染移除的组件上否则无法体现消失效果。避免在transition回调中修改状态transition的animation回调是动画配置参数不是事件回调。性能考量大量的组合过渡效果可能影响渲染性能建议控制同时执行动画的组件数量。ArkTS严格模式兼容在ArkTS中不能使用对象字面量作为类型声明必须定义显式的类不能使用Text组件上不存在的属性如maxWidth应使用constraintSize替代。详见本项目配套的《ArkTS常见编译错误修复指南》。五、总结特性说明触发时机组件通过if/ForEach插入或移除时自动触发核心APITransitionEffect.animation().combine()非对称效果TransitionEffect.asymmetric(appear, disappear)组合效果使用.combine()链式调用叠加多种动画典型场景列表增删、条件渲染、波纹扩散、通知弹出组件内转场是ArkUI中最简洁的动画方案适用于所有组件出现/消失的场景。掌握它之后配合animateTo显式动画可以覆盖绝大多数UI动画需求。