X叶域Q的主页-鸿蒙开发者社区-51CTO.COM
开始只写了点击切换图片效果,然后在运行调试的时候发现总是习惯性的想要滑动图片达到切换的目的。
针对此需求就开始研究起了图片轮播,研究触摸事件写完后突然发现了一个挺方便的轮播图组件,于是就有了如下内容。
先看展示:上图为触摸事件判断图片左右滑动,下图为轮播组件


一、图片滑动和点击切换效果
1、定义需要的变量
自定义按钮的文字,展示的图片列表,正在展示的图片和按钮选中的图片编号。
触摸事件需要判断用户滑动方向,需要记录一下开始和结束位置做判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| btnList: Array<string> = ["图片1","图片2","图片3","图片4"] imgList: Array<Resource> = [ $r("app.media.img1"), $r("app.media.img2"), $r("app.media.img3"), $r("app.media.img4"), ]
@State showImg: Resource = this.imgList[0]; @State selectImg: number = 0;
imgStartX: number = 0; imgEndX: number = 0;
|
2、按钮样式切换
- 当按钮被点击时,会执行一个动画过渡效果(
animateTo
),动画持续时间设定为 300 毫秒,在动画执行过程中,会更新this.selectImg
的值为当前点击按钮对应的index
,并且相应地更新this.showImg
为this.imgList
数组中对应索引位置的图片,以此来实现图片切换的效果。
- 按钮的字体颜色和背景颜色会根据
this.selectImg
的值与当前索引index
是否相等来决定是哪种颜色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Row(){ ForEach(this.btnList,(item: string, index)=>{ Button({ type: ButtonType.Normal, stateEffect: true}) { Text(item) .fontSize(14) .fontColor(this.selectImg===index ? Color.White:Color.Green) } .width('23%') .height("100%") .borderRadius(4) .backgroundColor(this.selectImg===index ? Color.Blue:Color.Gray) .onClick(() => { animateTo({duration: 300,}, () => { this.selectImg = index; this.showImg = this.imgList[this.selectImg]; }) }) }) } .justifyContent(FlexAlign.SpaceBetween) .width(260) .height(30)
|
3、触摸事件实现滑动切换效果
展示图片,每次只展示选中的那张图片
1 2 3 4
| Image(this.showImg) .height(140) .width(260) .borderRadius(8)
|
通过不同的触摸事件的类型来保存触摸点相对于应用窗口左上角的X坐标,根据需求需要下面三种
- 用户按下时记录按下时的位置
- 滑动后记录滑动后的位置
- 手指抬起时执行判断,切换图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| .onTouch((event) => { if(event.type == TouchType.Down){ this.imgStartX = event.touches[0].x; this.imgEndX = this.imgStartX; } else if(event.type == TouchType.Move){ this.imgEndX = event.touches[0].x; } else if(event.type == TouchType.Up){ if(this.imgStartX > this.imgEndX){ this.selectImg = (this.selectImg+1) % 4; animateTo({duration: 300}, () => { this.showImg = this.imgList[this.selectImg]; }) } else if(this.imgStartX < this.imgEndX){ this.selectImg = ((this.selectImg-1) % 4 + 4) % 4; animateTo({duration: 300=}, () => { this.showImg = this.imgList[this.selectImg]; }) } } })
|
这样就实现了滑动轮播效果,然后如果加上定时器可以实现自动轮播还可以根据需求修改样式,非常的灵活
1、轮播
非常方便这里就直接贴代码拉 (图片数据还是上面)
1 2 3 4 5 6 7 8 9 10 11 12 13
| private swiperController: SwiperController = new SwiperController();
Swiper(this.swiperController){ ForEach(this.imgList, (item: Resource) => { Image(item) .height(140) .width(260) .borderRadius(8) }) } .loop(true) .autoPlay(true) .interval(1000)
|
属性 |
类型 |
说明 |
loop |
boolean |
通过loop属性控制是否循环播放,该属性默认值为true |
autoPlay |
boolean |
Swiper通过设置autoPlay属性,控制是否自动轮播子组件。该属性默认值为false。 |
interval |
number |
autoPlay为true时,会自动切换播放子组件,子组件与子组件之间的播放间隔通过interval属性设置。interval属性默认值为3000,单位毫秒。 |
indicator |
DotIndicator | DigitIndicator | boolean |
通过indicator属性,开发者可以设置导航点相对于Swiper组件上下左右四个方位的位置,同时也可以设置每个导航点的尺寸、颜色、蒙层和被选中导航点的颜色。 |
vertical |
boolean |
当vertical为true时,表示在垂直方向上进行轮播;为false时,表示在水平方向上进行轮播。vertical默认值为false。 |
displayCount |
value: number | string | SwiperAutoFill, swipeByGroup?: boolean |
每页显示多个子页面 |
2、页面切换方式
Swiper支持手指滑动、点击导航点和通过控制器三种方式切换页面。
通过控制器切换页面,定义控制器。
1
| private swiperController: SwiperController = new SwiperController();
|
通过控制器滑动轮播
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Row(){ Button('Next') .onClick(() => { this.swiperController.showNext(); }) Button('Previous') .onClick(() => { this.swiperController.showPrevious(); }) Button('changeIndex-1') .onClick(() => { this.swiperController.changeIndex(0); }) }
|