惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
D
Docker
H
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
C
Check Point Blog
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
M
MIT News - Artificial intelligence
B
Blog RSS Feed
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
美团技术团队
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale

人人都是产品经理

为什么你的产品找不到差异化?90%的失败都卡在第一步上(下) – 人人都是产品经理, 3年从30万到1300万用户、获2200万美元融资,这个AI教育产品用“抽卡”破解了获客难题 – 人人都是产品经理, 园区招商系统怎么做才能真正帮到去化?我加了这一个功能,推广链接转发400次阅读过万 – 人人都是产品经理, AI大事件:OpenAI发完网络安全模型又搞药物研发,小鹏汽车要抓”DeepSeek时刻” – 人人都是产品经理, 电商不是卖货,是一场更残酷的产品经理实战 – 人人都是产品经理, 没想到,活动营销又回来了! – 人人都是产品经理, 为何All-in海外KOC:一场关于AI时代窗口期的豪赌 – 人人都是产品经理, 重新理解企业的内部协作 – 人人都是产品经理, 苹果的 AI 战略到底是什么? – 人人都是产品经理, 医疗智能体·第2讲——合规护城河:等保、PIPL与HIPAA的架构实战 – 人人都是产品经理, 向量知识库五步法:从“答非所问”到“精准回复” – 人人都是产品经理, 鸿蒙PC三方库构建总指挥HPKBUILD(sha)库为例 – 人人都是产品经理, 何时该用LLM?AI产品经理的LLM设计指南 – 人人都是产品经理, 医疗信息领域的需求方、决策方、准入方以及关注点(二) – 人人都是产品经理, 即梦涨价:一场被误读的「傲慢」 – 人人都是产品经理, 面试AI PM必答题:Hermes和OpenClaw的区别,如何讲清楚业务价值 – 人人都是产品经理, AI的下一张船票:世界模型——AI产品经理必须理解的技术拐点 – 人人都是产品经理, 小红书做GEO,怎么让AI信你?记住这 3 个重要信息 – 人人都是产品经理, 5 家印度 AI 初创公司,看看印度 AI 再做什么 – 人人都是产品经理, AI项目跨团队协作:产品技术业务如何不打架 – 人人都是产品经理, Agentic Workflow(智能体工作流):让AI从”答案生成器”变成”数字员工” – 人人都是产品经理, lycium_plusplus 项目全景解读:OpenHarmony 三方库构建的“大管家” – 人人都是产品经理, 从爆单救火到前置履约:两套预采策略,把生鲜大促履约效率拉满 – 人人都是产品经理, 什么时候该补货?我用一轮数据做了一个决定 – 人人都是产品经理, 从“机械兜底”到“动态分流”:AI客服重复进线治理的4大底层逻辑 – 人人都是产品经理, 抖音拼效率,红书拼洞察 – 人人都是产品经理, 全民狂欢与退潮——为什么龙虾这波热潮冷却得如此之快? – 人人都是产品经理, Stripe押注!MPP重塑全球支付 – 人人都是产品经理, 小红书GEO:AI引用你的内容,不是因为你对,而是因为你看起来可信 – 人人都是产品经理, 前百度副总裁押注办公Agent,日韩付费爆发,Manus迎来强劲对手 – 人人都是产品经理,
鸿蒙开发:自定义切换动画实现Swiper层叠滑动效果
程序员一鸣 · 2026-05-26 · via 人人都是产品经理

前言

本文基于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不仅仅可以实现平移上的改变,很多的效果,我们都可以实现,比如放大缩小,旋转等等。