鸿蒙应用开发实战【99】— 用户体验优化加载动画与触觉反馈

📅 2026/7/17 1:23:36
鸿蒙应用开发实战【99】— 用户体验优化加载动画与触觉反馈
鸿蒙应用开发实战【99】— 用户体验优化加载动画与触觉反馈本文是「号码助手全栈开发系列」第 99 篇持续更新中…开源社区https://openharmonycrossplatform.csdn.net前言优秀的用户体验不仅仅是功能完善——加载状态、转场动画和触觉反馈同样重要。号码助手项目在多个场景中应用了动画和 Loading 状态本篇总结 ArkUI 中的动画最佳实践。本篇涵盖AppAnimations 动画令牌、animateTo隐式动画、页面转场动画、LoadingProgress 加载状态、ohos.vibrator 触觉反馈、Skeleton 骨架屏。一、动画令牌系统文件common/theme/AppAnimations.etsimportcurvesfromohos.curvesexportclassAppAnimations{// 三档时长staticreadonlyDURATION_FAST:number160// 快速hover/按下staticreadonlyDURATION_NORMAL:number260// 常规转场/展开staticreadonlyDURATION_SLOW:number380// 慢速强调动画// 两条曲线staticreadonlyCURVE_STANDARD:ICurvecurves.cubicBezierCurve(0.2,0,0,1)// 平滑缓入缓出staticreadonlyCURVE_SPRING:ICurvecurves.springMotion(0.35,0.9)// 弹簧效果// 快捷方法staticstandard(duration:numberAppAnimations.DURATION_NORMAL):AnimateParam{return{duration,curve:AppAnimations.CURVE_STANDARD}}}二、animateTo 隐式动画ArkUI 最常用的动画方式是通过animateTo包裹状态变化// FAB 展开/收起动画privatetoggleFab():void{animateTo(AppAnimations.standard(AppAnimations.DURATION_NORMAL),(){this.fabExpanded!this.fabExpanded})}// 列表项出现动画ForEach(this.rows,(item:AppRow,index:number){AppListItem({item,selected:this.isSelected(item.binding.id!)}).opacity(this.rows.indexOf(item)this.visibleCount?1:0).translate({y:this.rows.indexOf(item)this.visibleCount?0:20})},(item:AppRow)item.binding.id!.toString())动画参数对照参数AppAnimations 值效果duration 160msFASTE’反馈型按钮按下duration 260msNORMAL转场型页面切换duration 380msSLOW展示型强调动画cubicBezier(0.2,0,0,1)CURVE_STANDARD自然平滑springMotion(0.35,0.9)CURVE_SPRING弹性回弹三、页面转场动画通过EnterTransition和ExitTransition定义页面切换动画EntryComponentstruct BackupPage{// 进入从右侧滑入 透明度EnterTransitionenterTransition:TransitionEffectTransitionEffect.slide(SlideEffect.Right).combine(TransitionEffect.opacity(1))// 退出从下侧滑出ExitTransitionexitTransition:TransitionEffectTransitionEffect.slide(SlideEffect.Bottom)}或者使用pageTransitionAPI// 页面级转场pageTransition(){PageTransitionEnter({duration:260,curve:AppAnimations.CURVE_STANDARD}).slide(SlideEffect.Right).translate({x:100})PageTransitionLeave({duration:160}).slide(SlideEffect.Left)}四、加载状态LoadingProgress4.1 全屏 Loading// HomePage 加载中展示if(this.loading){Column(){LoadingProgress().width(48).height(48).color(AppColors.PRIMARY)Text(加载中...).fontSize(14).fontColor(AppColors.TEXT_2).margin({top:12})}.width(100%).height(100%).justifyContent(FlexAlign.Center)}4.2 按钮内联 Loading// 备份按钮 LoadingRow(){if(this.backing){LoadingProgress().width(20).height(20).color(#FFFFFF)}else{Text(立即备份)}}.width(100%).height(46).onClick((){this.doBackup()})4.3 三态 UI 管理Stateloading:booleantrueStateloadError:string|nullnullbuild(){if(this.loading){// Loading 态this.LoadingView()}elseif(this.loadError){// 错误态this.ErrorView(this.loadError)}else{// 正常内容this.ContentView()}}五、触觉反馈HarmonyOS 提供ohos.vibrator模块实现触觉反馈import{vibrator}fromkit.SensorServiceKit// 短促点击反馈functionhapticTap():void{try{vibrator.startVibration({type:time,duration:10// 10ms},{usage:touch})}catch(e){// 设备不支持震动时静默忽略}}// 长按反馈functionhapticLongPress():void{try{vibrator.startVibration({type:time,duration:30// 30ms},{usage:touch})}catch(e){// 静默忽略}}使用场景// FAB 按钮点击Image($r(app.media.ic_add)).onClick((){hapticTap()// 触觉反馈this.toggleFab()})// 长按列表项进入选择模式Column().gesture(LongPressGesture({duration:500}).onAction((){hapticLongPress()// 长按震动this.enterSelectMode()}))六、Skeleton 骨架屏数据加载前展示骨架屏提升感知性能BuilderprivateSkeletonView(){Column(){// 统计卡片骨架Row(){ForEach([1,2,3],(){Column(){Row().width(60).height(16).borderRadius(8).backgroundColor(#1A141E2E)Row().width(40).height(32).borderRadius(8).backgroundColor(#1A141E2E).margin({top:8})}.padding(16).backgroundColor(#0F141E2E).borderRadius(16)})}.width(100%).justifyContent(FlexAlign.SpaceBetween)// 列表骨架ForEach([1,2,3,4],(){Row(){Circle().width(44).height(44).fill(#1A141E2E)Column(){Row().width(60%).height(14).borderRadius(7).backgroundColor(#1A141E2E)Row().width(40%).height(12).borderRadius(6).backgroundColor(#1A141E2E).margin({top:6})}.margin({left:12})}.width(100%).height(64).padding({left:16,right:16})})}.padding(16)}七、动画性能注意事项注意项原因建议难度避免重排layout 属性变化触发重新测量用opacity/translate代替改宽高低减少逐帧计算复杂动画卡顿使用springMotion代替逐帧 animate中动画复用每个组件的 animateTo 独立提取到动画令牌统一管理中在页面销毁时停止组件销毁后动画回调报错在aboutToDisappear中清理定时器高小结技术用途实现方式动画令牌统一管理时长和曲线AppAnimations类animateTo状态变化动画包裹状态更新代码页面转场页面间切换动画EnterTransition/ PageTransitionLoading加载中状态LoadingProgress 条件渲染触觉反馈按键/长按反馈ohos.vibratorSkeleton骨架屏纯 UI 组件填充占位如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.netHarmonyOS 动画开发指南https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-animationHarmonyOS 官方文档https://developer.huawei.com/consumer/cn/doc/HarmonyOS hilog文档https://developer.huawei.com/consumer/cn/doc/harmonyos-references/hilogHarmonyOS testinghttps://developer.huawei.com/consumer/cn/doc/harmonyos-guides/unit-testHarmonyOS 安全与权限https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-overview