鸿蒙开发:自定义切换动画实现Swiper层叠滑动效果

简介: customContentTransition不仅仅可以实现平移上的改变,很多的效果,我们都可以实现,比如放大缩小,旋转等等。

前言


本文基于Api13


Swiper组件默认情况下是无论是从左往右,还是从右往左,都是平移滑动,效果如下:



以上的效果是最常见的,基本上都够满足大部分的场景需求,也是很多主流App首选效果,但是,仍然有一部分需求,会不按常理出牌,这不,让实现一个层叠滑动的效果就来了,所谓的层叠,就是,在滑动条目的时候,上一个不动,下一个覆盖到上一个的上面进行滑动,为了更好的便于大家理解,简单的做一个小动画,模拟演示一下。


正常的平移滑动效果,两个条目会一起进行平移。



层叠效果滑动,可以看到,上一个条目是不会跟随移动的。



那么如何实现上一个条目不随着手势进行移动呢?这里就需要用到自定义页面切换动画了,也就是在手势滑动的时候,保持当前条目不动,让下一个条目进行移动,还有一点需要注意的是,那就是需要设置组件的堆叠顺序,使其要滑动的组件层级高于前一个组件。


实现之前,我们先了解一下自定义Swiper页面切换动画customContentTransition。


customContentTransition


customContentTransition是Swiper组件中的一个属性,主要用于页面切换动画,接收一个SwiperContentAnimatedTransition参数;它的作用,主要在于,在页面随着手势进行切换动画的过程中,会对视窗内所有页面进行逐帧触发回调,在这个回调中,我们就可以针对条目进行设置透明度、缩放比例、位移等属性来自定义切换动画。


/**
     * Custom swiper content transition animation.
     *
     * @param { SwiperContentAnimatedTransition } transition - custom content transition animation.
     * @returns { SwiperAttribute } the attribute of the swiper.
     * @syscap SystemCapability.ArkUI.ArkUI.Full
     * @crossplatform
     * @atomicservice
     * @since 12
     */
    customContentTransition(transition: SwiperContentAnimatedTransition): SwiperAttribute;


有一点需要注意的是,customContentTransition是自定义切换动画,但不会取消原有的动画,也就是说,我们在自定义动画的时候,原有的动画也是同步的执行的,为了让原有的动画不执行,我们可以设置主轴方向上负的位移(translate属性)来抵消页面滑动,这也是我们这个需求的主要实现方式。


准备数据


通过前边,我们已经知道,要实现前言中的需求,我们需要做的有两个动作,动作一,动态修改子元素的位移,我们可以通过translate属性来控制,动作二,动态改变子元素的层级权重,通过属性zIndex来设置。


基本UI如下,当然了,这只是一个简单的Demo案例,实际开发中,属性以及数据设置,要根据实际情况而定。


Swiper() {
        ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => {
          Text(index.toString())
            .width("100%")
            .height("100%")
            .backgroundColor(backgroundColor)
            .textAlign(TextAlign.Center)
            .translate({ x: this.translateList[index] })
            .zIndex(this.zIndexList[index])
        })
      }
      .height(200)


以上的案例,我简单定义了三个数组,一个用于数据加载的backgroundColors,一个用于位移的translateList,最后一个是用于设置层级权重的zIndexList。


实现自定义切换动画


实现这个层叠滑动,实现customContentTransition方法之前,有一点需要知道,那就是我们目前是往左滑动还是往右滑动,因为在最后一个条目节点需要做特殊的逻辑判断,往左还是往右,我们可以通过onGestureSwipe方法中偏移量进行判断。


extraInfo.currentOffset小于0,往左,否则往右。


.onGestureSwipe((_: number, extraInfo: SwiperAnimationEvent) => {
        let currentOffset = extraInfo.currentOffset
        this.isScrollLeft = currentOffset < 0
      })


在customContentTransition方法中,我们正常执行滑动抵消即可,首先是在同组页面往左滑或往右完全滑出视窗外时,我们需要重置属性值,这是非常重要的。


如何把当前的滑动进行抵消呢,很简单,当往左滑动时,使用页面在主轴方向上的长度减去移动比例乘以主轴长度即可,代码如下:viewIndex是当前的索引。


this.translateList[viewIndex] = proxy.mainAxisLength - proxy.position * proxy.mainAxisLength


往右滑动,直接负的移动比例乘以主轴长度,代码如下:


this.translateList[proxy.index] = -(proxy.position) * proxy.mainAxisLength


整个切换动画代码如下,在往左滑动的过程中,由于最后一个,需要动态切换为第一个索引,所以这里做了单独的逻辑处理。


.customContentTransition({
        timeout: 0,
        transition: (proxy: SwiperContentTransitionProxy) => {
          if (proxy.position <= 0 || proxy.position >= 1) {
            if (this.isScrollLeft) {
              if (proxy.index != this.translateList.length - 1) {
                this.translateList[proxy.index+1] = 0.0
                this.zIndexList[proxy.index+1] = 0
              }
            } else {
              this.translateList[proxy.index] = 0.0
              this.zIndexList[proxy.index] = 0
            }
          } else {
            if (this.isScrollLeft) {
              let viewIndex = proxy.index - 1
              if (viewIndex == -1) {
                this.translateList[this.translateList.length-1] =
                  proxy.mainAxisLength - proxy.position * proxy.mainAxisLength
                this.translateList[0] = 0
                this.zIndexList[0] = 1
              } else {
                this.translateList[viewIndex] = proxy.mainAxisLength - proxy.position * proxy.mainAxisLength
                this.zIndexList[viewIndex] = -1
              }
            } else {
              this.translateList[proxy.index] = -(proxy.position) * proxy.mainAxisLength
              this.zIndexList[proxy.index] = -1
            }
          }
        }
      })


通过以上的代码,一个层叠滑动效果就实现了,我们一起来看下最终的效果:


相关总结


customContentTransition不仅仅可以实现平移上的改变,很多的效果,我们都可以实现,比如放大缩小,旋转等等。


本文标签:HarmonyOS/ArkUI

相关文章
|
20天前
|
开发者
鸿蒙开发:资讯项目实战之项目初始化搭建
目前来说,我们的资讯项目只是往前迈了很小的一步,仅仅实现了项目创建,步虽小,但概念性的知识很多,这也是这个项目的初衷,让大家不仅仅可以掌握日常的技术开发,也能让大家理解实际的项目开发知识。
鸿蒙开发:资讯项目实战之项目初始化搭建
|
14天前
|
缓存 JavaScript IDE
鸿蒙开发:基于最新API,如何实现组件化运行
手动只是让大家了解切换的原理,在实际开发中,可不推荐手动,下篇文章,我们将通过脚本或者插件,快速实现组件化模块之间的切换,实现独立运行,敬请期待!
鸿蒙开发:基于最新API,如何实现组件化运行
|
20天前
|
SQL 弹性计算 数据库
鸿蒙5开发宝藏案例分享---优化应用时延问题
鸿蒙性能优化指南来了!从UI渲染到数据库操作,6大实战案例助你提升应用流畅度。布局层级优化、数据加载并发、数据库查询提速、相机资源延迟释放、手势识别灵敏调整及转场动画精调,全面覆盖性能痛点。附赠性能自检清单,帮助开发者高效定位问题,让应用运行如飞!来自华为官方文档的精华内容,建议收藏并反复研读,共同探讨更多优化技巧。
|
20天前
|
缓存
鸿蒙5开发宝藏案例分享---Swiper组件性能优化实战
本文分享了鸿蒙系统中Swiper组件的性能优化技巧,包括:1) 使用`LazyForEach`替代`ForEach`实现懒加载,显著降低内存占用;2) 通过`cachedCount`精准控制缓存数量,平衡流畅度与内存消耗;3) 利用`onAnimationStart`在抛滑时提前加载资源,提升构建效率;4) 添加`@Reusable`装饰器复用组件实例,减少创建开销。实际应用后,图库页帧率从45fps提升至58fps,效果显著。适合处理复杂列表或轮播场景,欢迎交流经验!
|
20天前
|
存储 C++ UED
鸿蒙5开发宝藏案例分享---优化应用包体积大小问题
本文分享了鸿蒙应用包体积优化的实用技巧,包括SO库压缩、HSP动态共享包、OHPM依赖冲突解决、按需加载和扫描工具定位优化点等方法。通过具体配置示例和实战经验,如启用`compressNativeLibs`、使用共享资源包、强制统一依赖版本以及动态导入功能模块,帮助开发者显著减少包体积,提升用户体验。文中还提供了图标优化、资源混淆和无用代码剔除等补充建议,助力打造更轻量的鸿蒙应用。
|
20天前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
20天前
|
数据库
鸿蒙5开发宝藏案例分享---跨线程性能优化指南
本文深入探讨鸿蒙系统跨线程序列化性能优化,借助DevEco Profiler工具定位序列化瓶颈。通过Sendable接口改造、数据瘦身等方法,将5万本书对象的序列化耗时从260ms+降至&lt;8ms,甚至&lt;1ms。总结避坑经验,建议常态化使用Profiler检测,避免传递大对象,提升多线程开发效率。
|
缓存 数据管理 Shell
鸿蒙5开发宝藏案例分享---性能分析简介
鸿蒙开发资源大揭秘!文中整理了HarmonyOS官方提供的100+场景化案例,涵盖性能优化、UI设计、设备适配等全链路内容。重点解析三大神级案例:折叠屏悬停交互、万人列表流畅滚动和服务卡片实时刷新,附带完整代码与避坑指南。通过精准搜索、代码移植和调试技巧,高效利用这些宝藏资源,助你省时省力避开开发陷阱。更有抖音级短视频流畅度优化方案等彩蛋等待探索!
|
20天前
|
Java
鸿蒙5开发宝藏案例分享---性能检测工具揭秘
鸿蒙性能优化工具全揭秘!本文详解官方隐藏的性能调优利器,包括静态检测(Code Linter)与动态检测(AppAnalyzer)。通过实战案例解析稀疏数组陷阱、循环更新状态变量等问题,并提供优化方案。同时附带高频性能规则速查表及黄金法则,助你高效避坑。开发时建议双开工具,实时检测问题,提升应用性能。
|
缓存 Shell 开发者
鸿蒙5开发宝藏案例分享---性能体验设计
这是一篇关于HarmonyOS性能优化的开发者实践指南。文章结合官方文档案例与代码实现,分享了流畅性设计的实用技巧,包括感知流畅性的核心原则、交互流畅实战案例(如列表滑动优化和点击响应加速)、视觉流畅的动效设计,以及性能检测工具ArkUI Inspector的使用方法。最后还提供了冷启动优化的具体策略。通过这些内容,帮助开发者打造60帧无卡顿的鸿蒙应用,实现操作响应快速、动效流畅的目标。