1# 创建弧形轮播 (ArcSwiper)(圆形屏幕推荐使用) 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @Hu_ZeQi--> 5<!--Designer: @jiangdayuan--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9ArcSwiper是弧形轮播组件,用于圆形屏幕使用,提供弧形轮播显示能力。具体用法请参考[ArcSwiper](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md)。 10 11在使用ArcSwiper组件之前,需要在代码中先导入ArcSwiper模块。 12 13```ts 14import { 15 ArcSwiper, 16 ArcSwiperAttribute, 17 ArcDotIndicator, 18 ArcDirection, 19 ArcSwiperController 20} from '@kit.ArkUI'; 21``` 22 23## 设置导航点样式 24 25ArcSwiper提供了默认的弧形导航点样式,导航点默认显示在ArcSwiper下方居中位置,开发者也可以通过[indicator](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#indicator)属性自定义弧形导航点的样式。 26 27通过indicator属性,开发者可以设置弧形导航点的方向,同时也可以设置导航点和被选中导航点的颜色。 28 29- 导航点使用默认样式 30 31 ```ts 32 ArcSwiper() { 33 Text('0') 34 .width(233) 35 .height(233) 36 .backgroundColor(Color.Gray) 37 .textAlign(TextAlign.Center) 38 .fontSize(30) 39 40 Text('1') 41 .width(233) 42 .height(233) 43 .backgroundColor(Color.Green) 44 .textAlign(TextAlign.Center) 45 .fontSize(30) 46 47 Text('2') 48 .width(233) 49 .height(233) 50 .backgroundColor(Color.Pink) 51 .textAlign(TextAlign.Center) 52 .fontSize(30) 53 } 54 ``` 55  56 57- 自定义导航点样式 58 59 导航点位于ArcSwiper组件6点钟方向,导航点颜色设为红色,被选中导航点颜色为蓝色。 60 61 ```ts 62 ArcSwiper() { 63 // ... 64 } 65 .indicator( 66 new ArcDotIndicator() 67 .arcDirection(ArcDirection.SIX_CLOCK_DIRECTION) // 设置导航点位于6点钟方向 68 .itemColor(Color.Red) // 设置导航点颜色为红色 69 .selectedItemColor(Color.Blue) // 设置选中导航点颜色为蓝色 70 ) 71 ``` 72  73 74## 控制页面切换方式 75 76ArcSwiper支持滑动手指、点击导航点、旋转表冠和控制控制器四种方式切换页面。以下示例展示通过控制控制器和旋转表冠翻页的方法。 77 78- 控制控制器翻页。 79 80 ```ts 81 // 导入ArcButton和ArcSwiper模块 82 import { 83 ArcButton, 84 ArcButtonOptions, 85 ArcButtonStatus, 86 ArcButtonStyleMode, 87 ArcButtonPosition, 88 ArcSwiper, 89 ArcSwiperAttribute, // ArcSwiper的属性依赖ArcSwiperAttribute对象导入,不建议删除该对象的引入。 90 ArcSwiperController 91 } from '@kit.ArkUI'; 92 93 @Entry 94 @Component 95 struct SwiperCustomAnimationExample { 96 private wearableSwiperController: ArcSwiperController = new ArcSwiperController(); 97 98 build() { 99 Column() { 100 Stack() { 101 ArcSwiper(this.wearableSwiperController) { 102 // ... 103 } 104 .vertical(true) 105 .indicator(false) 106 107 Column() { 108 ArcButton({ 109 options: new ArcButtonOptions({ 110 label: 'previous', 111 position: ArcButtonPosition.TOP_EDGE, 112 styleMode: ArcButtonStyleMode.EMPHASIZED_LIGHT, 113 onClick: () => { 114 this.wearableSwiperController.showPrevious(); // 通过controller切换到前一页 115 } 116 }) 117 }) 118 119 Blank() 120 121 ArcButton({ 122 options: new ArcButtonOptions({ 123 label: 'next', 124 position: ArcButtonPosition.BOTTOM_EDGE, 125 styleMode: ArcButtonStyleMode.EMPHASIZED_LIGHT, 126 onClick: () => { 127 this.wearableSwiperController.showNext(); // 通过controller切换到后一页 128 } 129 }) 130 }) 131 }.width('100%').height('100%') 132 } 133 } 134 } 135 } 136 ``` 137 138  139 140- 旋转表冠翻页。 141 142 ArcSwiper在获得焦点时能够响应旋转表冠的操作,用户可以通过旋转表冠来滑动ArcSwiper,从而浏览数据。 143 144 ```ts 145 ArcSwiper() { 146 // ... 147 } 148 .focusable(true) 149 .focusOnTouch(true) 150 .defaultFocus(true) 151 ``` 152 153 还可以通过设置[digitalCrownSensitivity](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#digitalcrownsensitivity)属性来调整表冠对事件响应的灵敏度,以适应不同规模的数据处理。在处理大量数据时,可以提高响应事件的灵敏度;而在处理少量数据时,则可以降低灵敏度设置。 154 155 ```ts 156 ArcSwiper() { 157 // ... 158 } 159 .digitalCrownSensitivity(CrownSensitivity.MEDIUM) 160 ``` 161 162## 设置轮播方向 163 164ArcSwiper支持水平和垂直方向上进行轮播,主要通过[vertical](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#vertical)属性控制。 165 166当vertical为true时,表示在垂直方向上进行轮播;为false时,表示在水平方向上进行轮播。vertical默认值为false。 167 168- 设置水平方向上轮播。 169 170 ```ts 171 ArcSwiper() { 172 // ... 173 } 174 .indicator(true) 175 .vertical(false) 176 ``` 177  178 179 180- 设置垂直方向轮播,导航点设为3点钟方向。 181 182 ```ts 183 ArcSwiper() { 184 // ... 185 } 186 .indicator(new ArcDotIndicator() 187 .arcDirection(ArcDirection.THREE_CLOCK_DIRECTION)) 188 .vertical(true) 189 ``` 190  191 192## 自定义切换动画 193 194ArcSwiper支持通过[customContentTransition](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#customcontenttransition)设置自定义切换动画,可以在回调中对视窗内所有页面逐帧设置透明度、缩放比例、位移、渲染层级等属性,从而实现自定义切换动画效果。 195 196```ts 197import { Decimal } from '@kit.ArkTS'; 198import { 199 ArcSwiper, 200 ArcSwiperAttribute, // ArcSwiper的属性依赖ArcSwiperAttribute对象导入,不建议删除该对象的引入。 201 ArcDotIndicator, 202 ArcDirection, 203 ArcSwiperController 204} from '@kit.ArkUI'; 205 206@Entry 207@Component 208struct SwiperCustomAnimationExample { 209 private MIN_SCALE: number = 0.1; 210 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange]; 211 @State opacityList: number[] = []; 212 @State scaleList: number[] = []; 213 214 aboutToAppear(): void { 215 for (let i = 0; i < this.backgroundColors.length; i++) { 216 this.opacityList.push(1.0); 217 this.scaleList.push(1.0); 218 } 219 } 220 221 build() { 222 Column() { 223 ArcSwiper() { 224 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 225 Text(index.toString()) 226 .width(233) 227 .height(233) 228 .fontSize(50) 229 .textAlign(TextAlign.Center) 230 .backgroundColor(backgroundColor) 231 .opacity(this.opacityList[index]) 232 .scale({ x: this.scaleList[index], y: this.scaleList[index] }) 233 }) 234 } 235 .customContentTransition({ 236 timeout: 1000, 237 transition: (proxy: SwiperContentTransitionProxy) => { 238 if (proxy.position <= -1 || proxy.position >= 1) { 239 // 页面完全滑出视窗外时,重置属性值 240 this.opacityList[proxy.index] = 1.0; 241 this.scaleList[proxy.index] = 1.0; 242 } else { 243 let position: number = Decimal.abs(proxy.position).toNumber(); 244 this.opacityList[proxy.index] = 1 - position; 245 this.scaleList[proxy.index] = 246 this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - position); 247 } 248 } 249 }) 250 }.width('100%') 251 } 252} 253``` 254 255 256 257## 实现侧滑返回 258 259ArcSwiper的滑动事件会与侧滑返回冲突,可以通过[手势拦截](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ongesturerecognizerjudgebegin)去判断ArcSwiper是否滑动到开头去拦截ArcSwiper的滑动手势,实现再次左滑返回上一页的功能。 260 261```ts 262import { 263 ArcSwiper, 264 ArcSwiperAttribute, // ArcSwiper的属性依赖ArcSwiperAttribute对象导入,不建议删除该对象的引入。 265 ArcDotIndicator, 266 ArcDirection, 267 ArcSwiperController 268} from '@kit.ArkUI'; 269 270@Entry 271@Component 272struct SwiperCustomAnimationExample { 273 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange]; 274 innerSelectedIndex: number = 0; 275 276 build() { 277 Column() { 278 ArcSwiper() { 279 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 280 Text(index.toString()) 281 .width(233) 282 .height(233) 283 .fontSize(50) 284 .textAlign(TextAlign.Center) 285 .backgroundColor(backgroundColor) 286 }) 287 } 288 .onAnimationStart((index: number, targetIndex: number) => { 289 this.innerSelectedIndex = targetIndex; 290 }) 291 .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, 292 others: Array<GestureRecognizer>): GestureJudgeResult => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态 293 if (current) { 294 let target = current.getEventTargetInfo(); 295 if (target && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) { 296 let swiperTarget = target as ScrollableTargetInfo; 297 if (swiperTarget instanceof ScrollableTargetInfo && 298 (swiperTarget.isBegin() || this.innerSelectedIndex === 0)) { // 此处判断swiperTarget.isBegin()或innerSelectedIndex === 0,表明ArcSwiper滑动到开头 299 let panEvent = event as PanGestureEvent; 300 if (panEvent && panEvent.offsetX > 0 && (swiperTarget.isBegin() || this.innerSelectedIndex === 0)) { 301 return GestureJudgeResult.REJECT; 302 } 303 } 304 } 305 } 306 return GestureJudgeResult.CONTINUE; 307 }) 308 }.width('100%') 309 } 310} 311``` 312