• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  ![indicator](figures/arcswiper_indicator.png)
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  ![indicator2](figures/arcswiper_indicator2.png)
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  ![controller](figures/arcswiper_controll.gif)
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  ![vertical](figures/arcswiper_indicator.png)
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  ![vertical2](figures/arcswiper_vertical.png)
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![customContentTransition](figures/arcswiper_custom_animation.gif)
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