在移动应用中,水平滑动浏览是仅次于上下滚动的第二高频手势。无论是 App 首次启动时的引导页、电商首页的广告轮播,还是新闻客户端的热点推荐——Swiper 轮播组件都是承载这些场景的核心 UI 单元。

HarmonyOS NEXT ArkUI 提供了 Swiper 组件——一个高度可定制的轮播容器。它不只是一个"可以滑动的容器":自动播放、循环模式、自定义指示器和翻页动画共同构成了完整的轮播交互体验。本文将深入讲解 Swiper 组件的完整 API,并构建一个"知识卡片浏览器"——支持滑动翻页、自动轮播、圆点指示器和手动导航。

关键词:HarmonyOS、ArkUI、Swiper、轮播组件、引导页、自动播放、指示器

一、Swiper 组件 API

1.1 基本用法

Swiper(controller?: SwiperController) {
  ForEach(this.cards, (card: StudyCard) => {
    Column() { /* 卡片内容 */ }
  })
}
.index(this.currentIndex)
.autoPlay(this.autoPlay)
.loop(true)
.interval(3000)
.indicator(Indicator.dot())
.duration(400)
.curve(Curve.EaseInOut)
.onChange((index: number) => {
  this.currentIndex = index;
})

核心属性与方法:

属性/方法 类型 说明
Swiper(controller) 构造参数 可选的 SwiperController,用于编程式翻页
.index() number 当前显示页索引(@State 绑定)
.autoPlay() boolean 是否自动轮播
.loop() boolean 是否循环播放(最后一页后回到第一页)
.interval() number 自动轮播间隔(毫秒)
.indicator() Indicator 指示器样式配置
.duration() number 翻页动画时长(毫秒)
.curve() Curve 翻页动画曲线
.onChange() callback 页面切换回调,参数为新索引

1.2 SwiperController

SwiperController 是 Swiper 的命令式 API,允许开发者通过代码控制翻页:

private swiperController: SwiperController = new SwiperController();

// 跳转到指定页
this.swiperController.changeIndex(3);

// 显示下一页
this.swiperController.showNext();

// 显示上一页
this.swiperController.showPrevious();

changeIndex(index) 是最常用的方法——它支持跳转到任意页面,并自动播放翻页动画。当用户点击指示器圆点或"跳过"按钮时,都需要通过 changeIndex 实现编程式跳转。

1.3 自动播放与循环

自动播放是 Swiper 在轮播广告中的核心价值:

.autoPlay(true)   // 开启自动轮播
.interval(3000)    // 每 3 秒翻页
.loop(true)        // 最后一页后回到第一页

looptrue 时,用户在最后一页继续滑动会回到第一页,反之亦然。自动播放也会在到达最后一页后回到第一页继续循环。如果 loopfalse,自动播放到达最后一页后停止。

需要注意的是,autoPlay 的值是一个 boolean,而非"是否开启自动播放的开关"。它可以直接绑定 @State 变量,让用户通过 Toggle 控制自动播放的开启与关闭:

@State autoPlay: boolean = false;

Toggle({ type: ToggleType.Switch, isOn: $$this.autoPlay })
  .onChange((value: boolean) => { this.autoPlay = value; })

1.4 Indicator 指示器

指示器是轮播组件最重要的附属 UI——它告诉用户"当前在第几页"和"总共有多少页"。ArkUI 提供了 Indicator 构建器:

.indicator(Indicator.dot()
  .itemWidth(8)
  .itemHeight(8)
  .selectedItemWidth(20)
  .selectedItemHeight(8)
  .color('#D0D0DD')          // 未选中圆点颜色
  .selectedColor('#1677FF'))  // 选中圆点颜色

.dot() 指定指示器样式为圆点(也支持 .digit() 数字样式)。selectedItemWidth 设为 20(未选中时 8)可以实现"选中圆点变长条"的动画效果——这种小细节是用户感知到轮播组件品质感的关键。

二、知识卡片浏览器的整体设计

2.1 页面架构

本文 Demo 构建一个"知识卡片浏览器",模拟学习类 App 的卡片浏览体验:

SwiperStudyPage
├── 标题栏 — "知识卡片" + 进度计数(1 / 6)
├── Swiper 区域(主体,占据剩余空间)
│   ├── 卡片 0: ArkUI 声明式开发
│   ├── 卡片 1: 状态管理
│   ├── 卡片 2: 组件化架构
│   ├── 卡片 3: 网络请求
│   ├── 卡片 4: 数据持久化
│   └── 卡片 5: 动画系统
└── 底部控制栏
    ├── 自动轮播开关(▶ / ⏸)
    ├── 上一页按钮
    └── 下一页按钮

2.2 数据结构

class StudyCard {
  id: number;
  category: string;   // 分类名(ArkUI / 状态管理 / 网络 / ...)
  catColor: string;    // 分类主题色
  emoji: string;       // 卡片图标
  title: string;       // 卡片标题
  summary: string;     // 摘要说明
  points: string[];    // 知识点列表(4 条)
}

6 张卡片覆盖了 HarmonyOS 开发的 6 个核心领域。每张卡片的 catColor 不同,确保视觉多样性。卡片采用 class 定义(而非 interface),原因与前文一致——ArkTS 不支持对象展开运算符,class 配合构造函数是创建对象的标准方式。

2.3 卡片布局

每张卡片是一个白色圆角矩形,包含五个元素:

  1. Emoji 图标(顶部):56px 大图标,视觉锚点
  2. 分类标签(图标下方):带主题色的文字 + 半透明背景
  3. 标题(标签下方):20px 加粗,黑色
  4. 摘要(标题下方):14px 灰色,最多 4 行
  5. 知识点列表(摘要下方):4 个"•"开头的条目,主题色圆点 + 灰色文字

卡片在 Swiper 内通过 padding 与屏幕边缘保持间距,露出淡灰色背景——这种"卡片在背景上滑动"的视觉效果比"卡片占满整屏"更有层次感。
在这里插入图片描述

三、Swiper 的核心配置

3.1 基础配置

Swiper(this.swiperController) {
  ForEach(this.getCards(), (card: StudyCard, idx: number) => {
    Column() {
      // 卡片内容
    }
  }, (card: StudyCard, idx: number) => card.id.toString())
}
.index(this.currentIndex)
.autoPlay(this.autoPlay)
.loop(true)
.interval(3000)
.indicator(Indicator.dot() ...)
.duration(400)
.curve(Curve.EaseInOut)
.onChange((index: number) => {
  this.currentIndex = index;
})

各配置项的含义:

  • loop(true):循环模式——第 6 页继续向前滑回到第 1 页
  • interval(3000):自动轮播时每 3 秒翻页一次
  • duration(400):翻页动画持续 400 毫秒
  • curve(Curve.EaseInOut):缓入缓出曲线,让翻页动画更自然
  • onChange:每次页面切换后更新 currentIndex,驱动进度文字和按钮状态更新

3.2 Indicator 的定制

.indicator(Indicator.dot()
  .itemWidth(8)
  .itemHeight(8)
  .selectedItemWidth(20)
  .selectedItemHeight(8)
  .color('#D0D0DD')
  .selectedColor('#1677FF'))

指示器的关键设计:选中圆点宽度为 20,未选中为 8——形成"加长选中圆点"的效果。颜色方面,未选中为浅灰(#D0D0DD),选中为品牌蓝(#1677FF),视觉对比清晰但不刺眼。

指示器位置默认在 Swiper 底部居中。在 Demo 中,指示器位于卡片下方、底部控制栏上方,这是引导页和卡片浏览器的常见布局。

3.3 SwiperController 的编程式控制

Demo 中三个操作都需要通过 SwiperController 实现:

private swiperController: SwiperController = new SwiperController();

goToPage(index: number): void {
  this.swiperController.changeIndex(index);
}

goNext(): void {
  let next = this.currentIndex + 1;
  if (next < this.getCards().length) {
    this.swiperController.changeIndex(next);
  }
}

goPrev(): void {
  let prev = this.currentIndex - 1;
  if (prev >= 0) {
    this.swiperController.changeIndex(prev);
  }
}

注意 goNext()goPrev() 中的边界检查:在非循环模式下(或需要特殊处理首尾页时),必须确保不会跳转到不存在的索引。Demo 中虽然 Swiper 开启了 loop(true),但"上一页"和"下一页"按钮仍然做了边界检查——按钮在到达边界时会变灰禁用,给用户明确的视觉反馈。

3.4 按钮的禁用状态

"上一页"和"下一页"按钮根据 currentIndex 动态调整样式:

// 上一页按钮:currentIndex > 0 时可用(蓝色),否则禁用(灰色)
.fontColor(this.currentIndex > 0 ? '#1677FF' : '#CCCCDD')
.backgroundColor(this.currentIndex > 0 ? '#F0F5FF' : '#F8F9FA')

// 下一页按钮同理
.fontColor(this.currentIndex < this.getCards().length - 1 ? '#1677FF' : '#CCCCDD')

这种即时反馈让用户清楚知道"还能不能继续翻"。如果 Swiper 的 looptrue,按钮理论上可以永远可点击——但 Demo 中选择在边界禁用按钮,因为循环模式下"从第 6 页跳到第 1 页"会让用户困惑,而手势滑动支持循环翻页更直觉。
在这里插入图片描述

四、进度计数器

标题栏右侧显示"1 / 6"格式的进度:

getProgressText(): string {
  return (this.currentIndex + 1).toString()
    .concat(' / ')
    .concat(this.getCards().length.toString());
}

currentIndex 从 0 开始(与数组索引一致),因此显示时加 1。这个数字随着 onChange 回调更新 currentIndex 而实时变化——每次翻页,进度文字同步更新。

进度计数器给用户两个信息:

  1. 当前在第几页:第一个数字
  2. 总共多少页:第二个数字

在引导页中,这种进度表示法比"仅显示圆点指示器"更精确——用户不仅知道相对位置(第 2 个圆点高亮),还知道绝对位置(第 2 页,共 6 页)。

五、自动播放控制

5.1 开关设计

底部控制栏左侧是自动播放开关:

Row() {
  Text(this.autoPlay ? '⏸' : '▶')
  Text(this.autoPlay ? '停止轮播' : '自动轮播')
}
.onClick(() => { this.toggleAutoPlay(); })

开关的文字和图标根据状态变化:

  • 未开启:显示 “▶ 自动轮播”(提示用户可以开启)
  • 已开启:显示 “⏸ 停止轮播”(提示用户可以暂停)

toggleAutoPlay() 直接翻转 this.autoPlay,而 Swiper 的 .autoPlay(this.autoPlay) 双向绑定会自动响应状态变化。

5.2 开启自动播放的体验

当用户点击"自动轮播"后,Swiper 每 3 秒自动翻到下一页。翻页动画使用 Curve.EaseInOut——开始和结束时缓慢、中间加速,模拟物理世界中的惯性运动。

如果在自动播放过程中用户手动滑动(或点击上一页/下一页按钮),自动播放的计时器会重置——这是 Swiper 的内置行为,确保用户的手动操作不会被自动播放打断。

六、6 张知识卡片的内容设计

每张卡片是一个 HarmonyOS 开发的核心知识点:

卡片 分类 标题 核心内容
0 ArkUI 声明式 UI 开发范式 @State、build()、if/else、ForEach
1 状态管理 状态驱动 UI 更新 @State、@Prop、@Link、@Provide/@Consume
2 组件化 组件化架构设计 @Component、@Builder、@Entry、组件通信
3 网络 HTTP 网络请求封装 http.createHttp()、request()、Promise、错误处理
4 数据持久化 本地数据存储方案 preferences、relationalStore、KVStore、加密
5 动画 动画与交互设计 animateTo、animation、transition、弹簧动画

每张卡片 4 个知识点,以"•"列表形式展现在摘要下方。这些知识点不是随机的——它们恰好覆盖了 HarmonyOS 应用开发的核心技术栈,让 Demo 不仅有展示价值,也有学习参考价值。

七、交互流程演示

7.1 首次进入

打开页面,Swiper 显示第 1 张卡片(ArkUI 声明式开发)。标题栏显示"1 / 6",指示器第一个圆点为蓝色长条,其余为灰色小圆点。"上一页"按钮为灰色禁用状态(当前在首页),"下一页"按钮为蓝色可用状态。

7.2 手势滑动

向左滑动(手指从右往左)。卡片以 EaseInOut 曲线翻到第 2 张(状态管理)。onChange 触发,currentIndex 更新为 1。标题栏进度变为"2 / 6",指示器第二个圆点变蓝变长,第一个恢复为灰色小圆点。两个导航按钮都变为蓝色可用状态(既不在首页也不在末页)。

7.3 按钮翻页

点击"下一页"按钮,翻到第 3 张卡片(组件化架构)。再点击"上一页",翻回第 2 张。按钮导航与手势滑动可以交替使用,currentIndex 始终保持同步。

7.4 自动轮播

点击"▶ 自动轮播",按钮切换为"⏸ 停止轮播"。Swiper 每 3 秒自动翻页,进度文字和指示器实时同步。翻到第 6 张后(loop 模式),自动回到第 1 张继续循环。点击"⏸ 停止轮播",自动播放暂停。

7.5 到达末页

连续点击"下一页"到达第 6 张(动画系统)。标题栏显示"6 / 6",指示器最后一个圆点高亮。"下一页"按钮变为灰色禁用状态,"上一页"仍为蓝色可用。

八、Swiper 的适用场景

8.1 引导页

App 首次启动时的引导页是 Swiper 最经典的应用。每页展示一个核心功能介绍,用户滑动浏览后点击"开始使用"进入主界面。本文 Demo 的知识卡片浏览器在结构上与引导页一致——Swiper + 指示器 + 导航按钮——只是内容从"功能介绍"换成了"知识卡片"。

8.2 广告轮播

电商和新闻 App 首页顶部的 Banner 轮播是 Swiper 的另一个高频场景。通常配合 autoPlay(true)loop(true) 实现自动循环播放,每 2-3 秒切换一张广告图。

8.3 卡片浏览

社交媒体和内容 App 中,全屏卡片式内容浏览(如 Tinder 的卡片滑动、抖音的上下滑动)本质上是 Swiper 的方向变体。ArkUI 的 Swiper 支持 .vertical(true) 纵向滑动模式,可以构建上下翻页的短视频或内容流。

8.4 图片浏览器

图片详情页中,左右滑动查看前后图片也是一个经典的 Swiper 用例。配合 Image 组件的缩放能力,可以实现完整的图片浏览体验。

九、总结

本文通过"知识卡片浏览器"这个实战案例,全面讲解了 ArkUI Swiper 轮播组件的使用方法。核心知识点包括:

  1. Swiper 基础 API:构造参数、index 绑定、loop 循环、interval 间隔
  2. SwiperControllerchangeIndex() 编程式翻页,支持跳转到任意页
  3. Indicator 指示器.dot() 圆点样式 + 尺寸/颜色定制
  4. 自动播放控制autoPlay + loop + interval 三件套,配合 Toggle 开关
  5. onChange 回调:页面切换时同步 currentIndex,驱动进度文字和按钮状态
  6. 导航按钮:上一页/下一页 + 边界禁用状态 + 动态颜色

Swiper 是移动应用中使用频率最高的组件之一。一个好的轮播体验不仅仅是"能左右滑动"——它需要清晰的进度指示、平滑的翻页动画、可控的自动播放和精确的编程式导航。ArkUI 的 Swiper 组件提供了这些能力的完整封装,让开发者可以将精力集中在卡片内容的设计上。


Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐