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