1# Creating a Swiper (Swiper) 2 3 4The [Swiper](../reference/apis-arkui/arkui-ts/ts-container-swiper.md) component is a container that is able to display child components in looping mode. It is typically used in scenarios such as display of recommended content on the home page. 5 6The **Swiper** component provides a preloading mechanism, which you can use to improve the swipe experience in complex scenarios. This mechanism allows for prebuilding and prerendering components when the main thread is idle. <!--Del-->For details, see [High-Performance Swiper Development](../performance/swiper_optimization.md).<!--DelEnd--> 7 8 9## Layout and Constraints 10 11The **Swiper** component follows its own size settings if they are configured. If the component does not have its own size settings configured, it follows the size of its parent component when the **prevMargin** or **nextMargin** attribute is set, or adapts its size to its child components otherwise. 12 13 14## Loop Playback 15 16The **loop** attribute sets whether to enable loop playback. Its default value is **true**. 17 18When **loop** is set to **true**, the user can switch to the previous or next page when they are on the first or last page. 19 20- Example of setting **loop** to **true**: 21 22```ts 23Swiper() { 24 Text('0') 25 .width('90%') 26 .height('100%') 27 .backgroundColor(Color.Gray) 28 .textAlign(TextAlign.Center) 29 .fontSize(30) 30 31 Text('1') 32 .width('90%') 33 .height('100%') 34 .backgroundColor(Color.Green) 35 .textAlign(TextAlign.Center) 36 .fontSize(30) 37 38 Text('2') 39 .width('90%') 40 .height('100%') 41 .backgroundColor(Color.Pink) 42 .textAlign(TextAlign.Center) 43 .fontSize(30) 44} 45.loop(true) 46``` 47 48 49 50- Example of setting **loop** to **false**: 51 52```ts 53Swiper() { 54 // ... 55} 56.loop(false) 57``` 58 59 60 61 62## Automatic Playback 63 64The **autoPlay** attribute sets whether to enable automatic playback for child component switching. Its default value is **false**. 65 66When **autoPlay** is set to **true**, automatic playback is enabled for child component switching. The playback interval is specified by the **interval** attribute, which is **3000** by default, in milliseconds. 67 68```ts 69Swiper() { 70 // ... 71} 72.loop(true) 73.autoPlay(true) 74.interval(1000) 75``` 76 77 78 79 80## Navigation Point Indicator 81 82The **Swiper** component comes with default navigation point and arrow styles, with navigation dots centered at the bottom and arrows hidden. 83 84With the **indicator** attribute, you can set the position of the navigation point indicator relative to the edges of the **Swiper** component, in addition to the size, color, and mask of each navigation point as well as the color of the selected navigation point. 85 86- Example of using the navigation point indicator in its default style: 87 88```ts 89Swiper() { 90 Text('0') 91 .width('90%') 92 .height('100%') 93 .backgroundColor(Color.Gray) 94 .textAlign(TextAlign.Center) 95 .fontSize(30) 96 97 Text('1') 98 .width('90%') 99 .height('100%') 100 .backgroundColor(Color.Green) 101 .textAlign(TextAlign.Center) 102 .fontSize(30) 103 104 Text('2') 105 .width('90%') 106 .height('100%') 107 .backgroundColor(Color.Pink) 108 .textAlign(TextAlign.Center) 109 .fontSize(30) 110} 111``` 112 113 114 115- Example of customizing the style of the navigation dots indicator, with the diameter of 30 vp, left margin of 0, and color of red: 116 117 118 119```ts 120Swiper() { 121 // ... 122} 123.indicator( 124 Indicator.dot() 125 .left(0) 126 .itemWidth(15) 127 .itemHeight(15) 128 .selectedItemWidth(30) 129 .selectedItemHeight(15) 130 .color(Color.Red) 131 .selectedColor(Color.Blue) 132) 133``` 134 135 136 137You can set the [displayArrow](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#displayarrow10) attribute of **Swiper** to control the size, position, color, and background of navigation point arrows, and whether to display arrows on mouse hover. 138 139- Example of using the navigation point arrows in the default style: 140 141```ts 142Swiper() { 143 // ... 144} 145.displayArrow(true, false) 146``` 147 148 149 150- Example of customizing the style of navigation point arrows as follows: 151 15218 vp size, blue color, on both sides of the component 153 154```ts 155Swiper() { 156 // ... 157} 158.displayArrow({ 159 showBackground: true, 160 isSidebarMiddle: true, 161 backgroundSize: 24, 162 backgroundColor: Color.White, 163 arrowSize: 18, 164 arrowColor: Color.Blue 165 }, false) 166``` 167 168 169 170## Page Switching Mode 171 172The **Swiper** component supports three page switching modes: using the swipe gesture, using the navigation dots indicator, and using the controller. The following example shows how to switch pages using the controller. 173 174```ts 175@Entry 176@Component 177struct SwiperDemo { 178 private swiperController: SwiperController = new SwiperController(); 179 180 build() { 181 Column({ space: 5 }) { 182 Swiper(this.swiperController) { 183 Text('0') 184 .width(250) 185 .height(250) 186 .backgroundColor(Color.Gray) 187 .textAlign(TextAlign.Center) 188 .fontSize(30) 189 Text('1') 190 .width(250) 191 .height(250) 192 .backgroundColor(Color.Green) 193 .textAlign(TextAlign.Center) 194 .fontSize(30) 195 Text('2') 196 .width(250) 197 .height(250) 198 .backgroundColor(Color.Pink) 199 .textAlign(TextAlign.Center) 200 .fontSize(30) 201 } 202 .indicator(true) 203 204 Row({ space: 12 }) { 205 Button('showNext') 206 .onClick(() => { 207 this.swiperController.showNext(); // Switch to the next page through the controller. 208 }) 209 Button('showPrevious') 210 .onClick(() => { 211 this.swiperController.showPrevious(); // Switch to the previous page through the controller. 212 }) 213 }.margin(5) 214 }.width('100%') 215 .margin({ top: 5 }) 216 } 217} 218``` 219 220 221 222 223## Playback Direction 224 225You can set the playback direction for the Swiper component through its **vertical** attribute. 226 227When **vertical** is set to **true**, vertical swiping is used. The default value of **vertical** is **false**. 228 229 230- Example of using horizontal swiping: 231 232```ts 233Swiper() { 234 // ... 235} 236.indicator(true) 237.vertical(false) 238``` 239 240 241 242 243 244- Example of using vertical swiping: 245 246```ts 247Swiper() { 248 // ... 249} 250.indicator(true) 251.vertical(true) 252``` 253 254 255 256 257 258## Child Components Per Page 259 260You can set the number of child components per page for the **Swiper** component through its [displayCount](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#attributes) attribute. 261 262```ts 263Swiper() { 264 Text('0') 265 .width(250) 266 .height(250) 267 .backgroundColor(Color.Gray) 268 .textAlign(TextAlign.Center) 269 .fontSize(30) 270 Text('1') 271 .width(250) 272 .height(250) 273 .backgroundColor(Color.Green) 274 .textAlign(TextAlign.Center) 275 .fontSize(30) 276 Text('2') 277 .width(250) 278 .height(250) 279 .backgroundColor(Color.Pink) 280 .textAlign(TextAlign.Center) 281 .fontSize(30) 282 Text('3') 283 .width(250) 284 .height(250) 285 .backgroundColor(Color.Blue) 286 .textAlign(TextAlign.Center) 287 .fontSize(30) 288} 289.indicator(true) 290.displayCount(2) 291``` 292 293 294 295## Customizing Transition Animation 296 297Use the [customContentTransition](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#customcontenttransition12) attribute to set a custom transition animation for **Swiper**. Define the animation by adjusting opacity, scale, translation, and rendering layer for all pages within the viewport frame by frame in the callback. 298 299```ts 300@Entry 301@Component 302struct SwiperCustomAnimationExample { 303 private DISPLAY_COUNT: number = 2 304 private MIN_SCALE: number = 0.75 305 306 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange] 307 @State opacityList: number[] = [] 308 @State scaleList: number[] = [] 309 @State translateList: number[] = [] 310 @State zIndexList: number[] = [] 311 312 aboutToAppear(): void { 313 for (let i = 0; i < this.backgroundColors.length; i++) { 314 this.opacityList.push(1.0) 315 this.scaleList.push(1.0) 316 this.translateList.push(0.0) 317 this.zIndexList.push(0) 318 } 319 } 320 321 build() { 322 Column() { 323 Swiper() { 324 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 325 Text(index.toString()).width('100%').height('100%').fontSize(50).textAlign(TextAlign.Center) 326 .backgroundColor(backgroundColor) 327 .opacity(this.opacityList[index]) 328 .scale({ x: this.scaleList[index], y: this.scaleList[index] }) 329 .translate({ x: this.translateList[index] }) 330 .zIndex(this.zIndexList[index]) 331 }) 332 } 333 .height(300) 334 .indicator(false) 335 .displayCount(this.DISPLAY_COUNT, true) 336 .customContentTransition({ 337 timeout: 1000, 338 transition: (proxy: SwiperContentTransitionProxy) => { 339 if (proxy.position <= proxy.index % this.DISPLAY_COUNT || proxy.position >= this.DISPLAY_COUNT + proxy.index % this.DISPLAY_COUNT) { 340 // When a group of pages is completely scrolled out of the viewport, reset the attribute values. 341 this.opacityList[proxy.index] = 1.0 342 this.scaleList[proxy.index] = 1.0 343 this.translateList[proxy.index] = 0.0 344 this.zIndexList[proxy.index] = 0 345 } else { 346 // When a group of pages is not scrolled out of the viewport, adjust the attribute values frame by frame for the left and right pages in the group based on the position. 347 if (proxy.index % this.DISPLAY_COUNT === 0) { 348 this.opacityList[proxy.index] = 1 - proxy.position / this.DISPLAY_COUNT 349 this.scaleList[proxy.index] = this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - proxy.position / this.DISPLAY_COUNT) 350 this.translateList[proxy.index] = - proxy.position * proxy.mainAxisLength + (1 - this.scaleList[proxy.index]) * proxy.mainAxisLength / 2.0 351 } else { 352 this.opacityList[proxy.index] = 1 - (proxy.position - 1) / this.DISPLAY_COUNT 353 this.scaleList[proxy.index] = this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - (proxy.position - 1) / this.DISPLAY_COUNT) 354 this.translateList[proxy.index] = - (proxy.position - 1) * proxy.mainAxisLength - (1 - this.scaleList[proxy.index]) * proxy.mainAxisLength / 2.0 355 } 356 this.zIndexList[proxy.index] = -1 357 } 358 } 359 }) 360 }.width('100%') 361 } 362} 363``` 364 365 366 367