写点什么

鸿蒙 Next 轮播组件 Swiper 使用了解

作者:auhgnixgnahz
  • 2025-06-25
    北京
  • 本文字数:5007 字

    阅读完需:约 16 分钟

本文介绍一下轮播组件 Swiper 的基本使用,各属性的含义已在代码中注释说明,可以通过动态修改,查看各属性起到的作用。


通过一个 Row 容器组件添加属性动画,设置动画持续时间与 swiper 播放时间匹配,实现一个带进度的指示器,如图。


看一下效果图:



源码


@Entry@ComponentV2struct SwiperTest{  private swiperController: SwiperController = new SwiperController();  datas:string[]=['0','1','2','3','4','5','6'];  @Local autoPlay:boolean = true//是否自动播放  @Local loop:boolean = true//是否开启循环  @Local interval:number=4000 //自动播放时播放的时间间隔  @Local duration:number=1000 //子组件切换的动画时长  @Local itemSpace:number=5 //子组件与子组件之间间隙  @Local displayCount:number=1  //视窗内元素显示个数  @Local nextMargin:number=35  //设置后边距,用于露出后一项的一小部分  @Local prevMargin:number=35  //设置前边距,用于露出前一项的一小部分  @Local showBackground:boolean=true  //箭头底板是否显示  @Local isSidebarMiddle:boolean=true  //箭头显示位置  @Local displayArrow:boolean=true  //箭头显示  @Local indicator:IndicatorComponentController | DotIndicator | DigitIndicator | boolean=    new DotIndicator()    .itemWidth(15)    .itemHeight(15)    .selectedItemWidth(15)    .selectedItemHeight(15)    .color(Color.Gray)    .selectedColor(Color.Blue)  //组件控制器
@Local slide: boolean = false; //判断页面是否跟手滑动 @Local currentIndex: number=0 @Local changeDuration: number=this.interval build() { Column({space:10}){ Swiper(this.swiperController){ ForEach(this.datas,(item: string, index:number)=>{ Text(item.toString()) .width('100%') .height(160) .backgroundColor(getRandomColor()) .textAlign(TextAlign.Center) .fontSize(30) }) } .index(this.currentIndex) //当前在容器中显示的子组件的索引值 .autoPlay(this.autoPlay) //是否自动播放 .interval(this.interval) //自动播放时播放的时间间隔 .indicator(this.indicator)// 设置圆点导航点样式 .loop(this.loop)//是否开启循环 .duration(this.duration) //子组件切换的动画时长 .vertical(false) //是否为纵向滑动 .itemSpace(this.itemSpace) //子组件与子组件之间间隙 .displayMode(SwiperDisplayMode.STRETCH) //主轴方向上元素排列的模式 .cachedCount(2) //预加载子组件个数 .disableSwipe(false) //禁用组件滑动切换功能 .curve(Curve.Linear) //动画曲线 .displayCount(this.displayCount) //视窗内元素显示个数 .effectMode(EdgeEffect.Spring) //边缘滑动效果 .displayArrow(this.displayArrow?{ // 设置导航点箭头样式 showBackground: this.showBackground, //设置箭头底板是否显示 isSidebarMiddle: this.isSidebarMiddle, //设置箭头显示位置 true时箭头居中显示在swiper组件两侧,为false时显示在导航点指示器两侧 backgroundSize: 24, //设置底板大小 backgroundColor: Color.White, //设置底板颜色 arrowSize: 18, //设置箭头大小 arrowColor: Color.Blue //设置箭头颜色 }:false , false) .nextMargin(this.nextMargin) //设置后边距,用于露出后一项的一小部分 .prevMargin(this.prevMargin) //设置前边距,用于露出前一项的一小部分 .indicatorInteractive(true) //禁用组件导航点交互功能 .onAppear(()=>{ this.currentIndex=0 }) //当前显示的子组件索引变化时触发该事件,返回值为当前显示的子组件的索引值 .onChange((index: number) => { this.currentIndex = index this.changeDuration =this.interval console.info(index.toString()); }) //在页面跟手滑动过程中 currentOffset Swiper当前显示元素在主轴方向上,相对于Swiper起始位置的位移 .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => { this.slide = true; if (extraInfo.currentOffset > 200 && this.currentIndex > 0) { this.currentIndex = index - 1; } console.info("index: " + index); console.info("current offset: " + extraInfo.currentOffset); }) //切换动画开始时触发该回调。参数为动画开始前的index值 .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); }) Text('自定义进度条指示器') this.progressComponent() Row(){ Button('自动播放'+(this.autoPlay?'开':'关')).onClick(()=>{ this.autoPlay=!this.autoPlay }) Column(){ Text("自动播放时间间隔") Counter() { Text(this.interval.toString()) }.width(120) .onInc(() => { this.interval+=1000; }) .onDec(() => { if (this.interval>0) { this.interval-=1000; } }) } Button('循环'+(this.loop?'开':'关')).onClick(()=>{ this.loop=!this.loop }) } Row(){ Button('圆点指示器').onClick(()=>{ this.indicator= new DotIndicator() .itemWidth(8) //圆点导航指示器的宽 .itemHeight(8) .selectedItemWidth(16) //选中Swiper组件圆点导航指示器的宽 .selectedItemHeight(8) .color(Color.Gray) .selectedColor(Color.Blue) .maxDisplayCount(9)//导航点显示个数最大值 }) Button('数字指示器').onClick(()=>{ this.indicator=Indicator.digit() // 设置数字导航点样式 .top(200) .fontColor(Color.Gray) .selectedFontColor(Color.Gray) .digitFont({ size: 20, weight: FontWeight.Bold }) .selectedDigitFont({ size: 20, weight: FontWeight.Normal }) }) Button('取消指示器').onClick(()=>{ this.indicator=false }) } Row(){ Column(){ Text("切换动画时长") Counter() { Text(this.duration.toString()) }.width(120) .onInc(() => { this.duration+=100; }) .onDec(() => { if (this.duration>0) { this.duration-=100; } }) } Column(){ Text("组件间隙") Counter() { Text(this.itemSpace.toString()) }.width(120) .onInc(() => { this.itemSpace+=1; }) .onDec(() => { if (this.itemSpace>0) { this.itemSpace-=1; } }) } } Row(){ Column(){ Text("视窗内元素个数") Counter() { Text(this.displayCount.toString()) } .onInc(() => { this.displayCount+=1; }) .onDec(() => { if (this.displayCount>1) { this.displayCount-=1; } }) } Column(){ Text("前边距") Counter() { Text(this.prevMargin.toString()) } .onInc(() => { this.prevMargin+=1; }) .onDec(() => { if (this.prevMargin>0) { this.prevMargin-=1; } }) } Column(){ Text("后边距") Counter() { Text(this.nextMargin.toString()) } .onInc(() => { this.nextMargin+=1; }) .onDec(() => { if (this.nextMargin>0) { this.nextMargin-=1; } }) } } Row(){ Button('箭头背景'+(this.showBackground?'显示':'隐藏')).onClick(()=>{ this.showBackground=!this.showBackground }) Button('箭头'+(this.isSidebarMiddle?'swiper两侧':'指示器两侧')).onClick(()=>{ this.isSidebarMiddle=!this.isSidebarMiddle }) Button('箭头'+(this.displayArrow?'显示':'隐藏')).onClick(()=>{ this.displayArrow=!this.displayArrow }) } } } //自定义进度条指示器 @Builder progressComponent() { Row({ space: 5 }) { ForEach(this.datas, (item: string, index: number) => { Stack({ alignContent: Alignment.Start }) { Row() .zIndex(0) .width("100%") .height(2) .borderRadius(2) .backgroundColor(Color.Grey) Row() .zIndex(1) .width(this.currentIndex >= index && !this.slide ? '100%' : '0') .height(2) .borderRadius(2) .backgroundColor(Color.White) .animation(!this.slide ? { duration: this.changeDuration, curve: Curve.Linear, iterations: 1, playMode: PlayMode.Normal, onFinish: () => { if (this.currentIndex === this.datas.length - 1) { this.changeDuration=0 this.currentIndex = -1; } } } : { duration: 0, iterations: 1 }) Row() .zIndex(2) .width(this.currentIndex >= index && this.slide ?'100%':'0') .height(2) .borderRadius(2) .backgroundColor(Color.White) } .width('100%') .height(2) .borderRadius(2) .backgroundColor(this.currentIndex >= index && this.slide ? Color.White : Color.Grey) .layoutWeight(1) }) } .width('70%') .height(50) .backgroundColor(getRandomColor()) }}export function getRandomColor(): string { let letters = '0123456789abcdef' let color = '#'
for (let i = 0; i < 6; i++) { // 生成0-15的随机数 const randomIndex = Math.floor(Math.random() * 16) // 添加随机字符 color += letters[randomIndex] } return color}
复制代码


发布于: 刚刚阅读数: 4
用户头像

auhgnixgnahz

关注

还未添加个人签名 2018-07-10 加入

欢迎关注:HarmonyOS开发笔记

评论

发布
暂无评论
鸿蒙Next轮播组件Swiper使用了解_鸿蒙Next_auhgnixgnahz_InfoQ写作社区