在HarmonyOS NEXT中使用Swiper组件进行页面布局时,为了提供更好的用户体验,我们可以实现一些自定义的动画效果以及自定义指示器。以下是两个具体的实现方案:
场景一:Swiper页面支持自定义动画
要实现Swiper页面支持自定义动画,我们需要设置Swiper组件的属性,并添加相应的事件处理程序来控制页面之间的过渡效果。
@Entry
@Component
struct CustomSwiperPage {
private currentIndex: number = 0;
private scaleArray: number[] = [];
private startSwiperOffset: number = 0;
private MAX_SCALE: number = 1.0; // 最大缩放值
private MIN_SCALE: number = 0.7; // 最小缩放值
private DRAGGING_MAX_DISTANCE: number = 200; // 拖拽的最大距离用于计算缩放值
build() {
Swiper()
.nextMargin(50)
.prevMargin(50)
.displayMode(SwiperDisplayMode.STRETCH)
.onChange((index) => {
console.info('changeIndex: ' + index);
this.currentIndex = index;
this.scaleArray[this.currentIndex] = this.MAX_SCALE;
if (this.currentIndex === 0) {
this.scaleArray[this.scaleArray.length - 1] = this.MIN_SCALE;
} else {
this.scaleArray[this.currentIndex - 1] = this.MIN_SCALE;
}
if (this.currentIndex === this.scaleArray.length - 1) {
this.scaleArray[0] = this.MIN_SCALE;
} else {
this.scaleArray[this.currentIndex + 1] = this.MIN_SCALE;
}
})
.customContentTransition({
timeout: 1000,
transition: (proxy) => {
if (this.startSwiperOffset === 0) {
this.startSwiperOffset = proxy.position * proxy.mainAxisLength;
console.info('startSwiperOffset: ' + this.startSwiperOffset);
}
let offset: number = proxy.position * proxy.mainAxisLength;
let currentScale: number = this.scaleArray[proxy.index];
let nextIndex = (proxy.index === this.scaleArray.length - 2 ? 0 : proxy.index + 1);
let preIndex = (proxy.index === 0 ? this.scaleArray.length - 2 : proxy.index - 1);
let nextScale: number = this.scaleArray[nextIndex];
let preScale: number = this.scaleArray[preIndex];
let distance = Math.abs(offset);
currentScale = this.MAX_SCALE - Math.min(distance / this.DRAGGING_MAX_DISTANCE, this.MAX_SCALE - this.MIN_SCALE);
if (this.startSwiperOffset > offset) {
nextScale = this.MIN_SCALE + Math.min(distance / this.DRAGGING_MAX_DISTANCE, this.MAX_SCALE - this.MIN_SCALE);
preScale = this.MIN_SCALE;
} else {
preScale = this.MIN_SCALE + Math.min(distance / this.DRAGGING_MAX_DISTANCE, this.MAX_SCALE - this.MIN_SCALE);
nextScale = this.MIN_SCALE;
}
this.scaleArray[this.currentIndex] = currentScale;
this.scaleArray[nextIndex] = nextScale;
this.scaleArray[preIndex] = preScale;
}
});
}
}
场景二:Swiper指示器距离底部位置
为了将Swiper的指示器放在距离底部特定位置,可以将Swiper分成两部分:内容区和指示器区。
@Entry
@Component
struct SwiperPageWithCustomIndicator {
private bannerInfo: number[] = [1, 2, 3, 4];
private dataList: Color[] = [Color.Gray, Color.Yellow, Color.Blue, Color.Pink, Color.Orange];
build() {
Column() {
Swiper() {
ForEach(this.bannerInfo, (item: number, index: number) => {
Column() {
Column() // Swiper内容区域
.width("100%")
.height(200)
.borderRadius("8vp")
.backgroundColor(this.dataList[index]);
Column() // 指示点区域
.width('100%')
.height(35)
.indicator(
new DotIndicator()
.bottom(5)
.itemWidth("8vp")
.itemHeight("8vp")
.selectedItemWidth("10vp")
.selectedItemHeight("10vp")
.color(Color.Green)
.selectedColor(Color.Orange)
);
}
});
}
.cachedCount(2)
.autoPlay(true)
.interval(3000)
.vertical(false)
.loop(true)
.margin({ left: "16vp", right: "16vp" });
}
}
}
场景三:Swiper自定义指示器
目前Swiper自带的指示器位置限定比较固定,不能完全靠底部、左边或者右边以及不能调整指示器中间间距,因此可以考虑自定义指示器,将指示器位置定位到我们所需的地方。
方案:
给Swiper自带指示器设置.indicator(false),然后在Swiper组件下面写一个自定义的指示器。
// 自定义指示器,可以通过定位
Row() {
ForEach(this.data, (item: string, index: number) => {
Column()
.width(this.currentIndex === index ? 10 : 5)
.height(5)// 设置指示点中间间距
.margin(5)
.borderRadius(5)
.backgroundColor(Color.Green)
.backgroundColor(this.currentIndex === index ? Color.Red : Color.Gray)
}, (item: string) => item)
}
//设置指示点距离Swiper上下的距离
.margin({ top: 5 })
// 设置指示点在Swiper的左边或者右边或者其他地方
// .position({x:0,y:300})
标签:index,SCALE,MIN,number,HarmonyOS,scaleArray,Swiper,页面
From: https://blog.51cto.com/u_15171169/11990927