HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变
HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变 现在需求是轮播图,滑动到第一个会缩放放大,其他的还是不变,有三方库吗
6 回复
使用 Swiper 实现轮播,通过 customContentTransition 接口,自定义切换动画变化透明度、缩放页面、抵消系统默认位移、渲染层级等。下面代码实现切换过程中两边缩放效果。开发者可参考 demo 中的实现,稍作修改。

@Entry
@Component
struct Index {
@State items: string[] = ['1', '2', '3', '4', '5']
@State scaleList: number[] = [0.8, 1, 0.8, 0.8, 0.8];
build() {
Swiper() {
ForEach(this.items, (item: string, index: number) => {
Text(item)
.textAlign(TextAlign.Center)
.width('100%')
.height(300)
.backgroundColor('#999')
.fontColor('#fff')
.fontSize(30)
.scale({ x: this.scaleList[index], y: this.scaleList[index] })
}, (item: string) => item)
}
.width('100%')
.prevMargin(50)
.nextMargin(50)
.index(1)
.interval(5000)
.loop(true)
.indicator(false)
.margin({ top: 100 })
.customContentTransition({
timeout: 1000,
transition: (proxy: SwiperContentTransitionProxy) => {
const scale = 0.8
const scaleFactor = 1 - scale * Math.abs(proxy.position);
this.scaleList[proxy.index] = Math.max(scaleFactor, scale);
}
})
}
}
更多关于HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
楼上回复的非常棒,不过如果想要使用三方库,可以参考链接:https://ohpm.openharmony.cn/#/cn/detail/@abner%2Fbanner,
期待HarmonyOS能在未来带来更多创新的技术和理念。
推荐使用Swiper组件:
// xxx.ets
class MyDataSource implements IDataSource {
private list: number[] = [];
constructor(list: number[]) {
this.list = list;
}
totalCount(): number {
return this.list.length;
}
getData(index: number): number {
return this.list[index];
}
registerDataChangeListener(listener: DataChangeListener): void {
}
unregisterDataChangeListener() {
}
}
@Entry
@Component
struct SwiperExample {
private swiperController: SwiperController = new SwiperController();
private data: MyDataSource = new MyDataSource([]);
aboutToAppear(): void {
let list: number[] = [];
for (let i = 1; i <= 10; i++) {
list.push(i);
}
this.data = new MyDataSource(list);
}
build() {
Column({ space: 5 }) {
Swiper(this.swiperController) {
LazyForEach(this.data, (item: string) => {
Text(item.toString())
.width('90%')
.height(160)
.backgroundColor(0xAFEEEE)
.textAlign(TextAlign.Center)
.fontSize(30)
}, (item: string) => item)
}
.cachedCount(2)
.index(1)
.autoPlay(true)
.interval(4000)
.loop(true)
.indicatorInteractive(true)
.duration(1000)
.itemSpace(5)
.prevMargin(35)
.nextMargin(35)
.indicator( // 设置圆点导航点样式
new DotIndicator()
.itemWidth(15)
.itemHeight(15)
.selectedItemWidth(15)
.selectedItemHeight(15)
.color(Color.Gray)
.selectedColor(Color.Blue))
.displayArrow({ // 设置导航点箭头样式
showBackground: true,
isSidebarMiddle: true,
backgroundSize: 24,
backgroundColor: Color.White,
arrowSize: 18,
arrowColor: Color.Blue
}, false)
.curve(Curve.Linear)
.onChange((index: number) => {
console.info(index.toString());
})
.onScrollStateChanged((event: ScrollState) => {
console.info("event: " + event);
})
.onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
console.info("index: " + index);
console.info("current offset: " + extraInfo.currentOffset);
})
.onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
console.info("index: " + index);
console.info("targetIndex: " + targetIndex);
console.info("current offset: " + extraInfo.currentOffset);
console.info("target offset: " + extraInfo.targetOffset);
console.info("velocity: " + extraInfo.velocity);
})
.onAnimationEnd((index: number, extraInfo: SwiperAnimationEvent) => {
console.info("index: " + index);
console.info("current offset: " + extraInfo.currentOffset);
})
Row({ space: 12 }) {
Button('showPrevious')
.onClick(() => {
this.swiperController.showPrevious();
})
Button('showNext')
.onClick(() => {
this.swiperController.showNext();
})
}.margin(5)
Row({ space: 5 }) {
Button('FAST 0')
.onClick(() => {
this.swiperController.changeIndex(0, SwiperAnimationMode.FAST_ANIMATION);
})
Button('FAST 3')
.onClick(() => {
this.swiperController.changeIndex(3, SwiperAnimationMode.FAST_ANIMATION);
})
Button('FAST ' + 9)
.onClick(() => {
this.swiperController.changeIndex(9, SwiperAnimationMode.FAST_ANIMATION);
})
}.margin(5)
}.width('100%')
.margin({ top: 5 })
}
}

在HarmonyOS Next中实现显示三个轮播项且第一项放大的效果,可通过以下步骤实现:
- 使用
Swiper组件创建轮播容器,设置displayCount为3显示三项 - 通过
Swiper的onChange事件监听当前激活项索引 - 在子项组件中使用
scale属性实现缩放效果,根据当前索引判断:- 当索引为0时应用放大变换(如
scale({x:1.2,y:1.2})) - 其他索引保持正常尺寸(
scale({x:1,y:1}))
- 当索引为0时应用放大变换(如
- 结合
animateTo添加平滑过渡动画
关键代码结构:
@State currentIndex: number = 0
Swiper({
index: this.currentIndex,
displayCount: 3,
onChange: (index: number) => {
this.currentIndex = index
}
}) {
ForEach(this.data, (item, index) => {
Image(item.src)
.scale({
x: this.currentIndex === index ? 1.2 : 1,
y: this.currentIndex === index ? 1.2 : 1
})
.animation({...})
})
}
在HarmonyOS Next中实现轮播图并控制第一个元素缩放,可以通过以下方式:
-
使用Swiper组件:这是HarmonyOS内置的轮播组件,支持循环滑动和自定义指示器。
-
结合自定义动画:
- 在
onChange事件中监听当前激活项 - 通过条件判断,为第一个元素添加缩放动画
- 使用
animateTo方法或属性动画实现缩放效果
- 在
-
示例代码框架:
@State currentIndex: number = 0
Swiper(this.currentIndex) {
ForEach(this.imageList, (item, index) => {
Image(item)
.scale(this.currentIndex === 0 ? { x: 1.2, y: 1.2 } : { x: 1.0, y: 1.0 })
.animation({ duration: 300, curve: Curve.EaseInOut })
})
}
.onChange((index: number) => {
this.currentIndex = index
})
- 关于三方库:目前HarmonyOS生态还在完善中,建议优先使用官方组件实现。可以关注华为开发者联盟的更新,看是否有相关UI库发布。
这种方式完全基于原生能力,性能更好,且无需依赖第三方库。

