鸿蒙开发:自定义切换动画实现Swiper层叠滑动效果
前言
本文基于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
- 0回答
- 1粉丝
- 0关注
- 如何实现上下切换的页面间跳转动画
- 鸿蒙开发:切换至基于rcp的网络请求
- HarmonyOS NEXT 鸿蒙实现自定义组件插槽
- 「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现
- 鸿蒙-自定义相机拍照
- 自定义组件之<二>自定义圆环(Ring)
- 187.HarmonyOS NEXT系列教程之列表切换案例交互实现详解
- HarmonyOS ArkTS中视频播放Video组件实现竖屏到横屏切换
- 鸿蒙开发:自定义一个Toast
- 自定义组件之<八>自定义下拉刷新(RefreshList)
- 自定义组件之<三>自定义标题栏(TitleBar)
- 自定义组件之<四>自定义对话框(Dialog)
- 自定义组件之<五>自定义对话框(PromptAction)
- 自定义组件之<六>自定义饼状图(PieChart)
- 自定义组件之<七>自定义组件之插槽(slot)