鸿蒙新特性:Swiper 轮播组件——构建知识卡片浏览器
在移动应用中,水平滑动浏览是仅次于上下滚动的第二高频手势。无论是 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) // 最后一页后回到第一页
当 loop 为 true 时,用户在最后一页继续滑动会回到第一页,反之亦然。自动播放也会在到达最后一页后回到第一页继续循环。如果 loop 为 false,自动播放到达最后一页后停止。
需要注意的是,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 卡片布局
每张卡片是一个白色圆角矩形,包含五个元素:
- Emoji 图标(顶部):56px 大图标,视觉锚点
- 分类标签(图标下方):带主题色的文字 + 半透明背景
- 标题(标签下方):20px 加粗,黑色
- 摘要(标题下方):14px 灰色,最多 4 行
- 知识点列表(摘要下方):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 的 loop 为 true,按钮理论上可以永远可点击——但 Demo 中选择在边界禁用按钮,因为循环模式下"从第 6 页跳到第 1 页"会让用户困惑,而手势滑动支持循环翻页更直觉。
四、进度计数器
标题栏右侧显示"1 / 6"格式的进度:
getProgressText(): string {
return (this.currentIndex + 1).toString()
.concat(' / ')
.concat(this.getCards().length.toString());
}
currentIndex 从 0 开始(与数组索引一致),因此显示时加 1。这个数字随着 onChange 回调更新 currentIndex 而实时变化——每次翻页,进度文字同步更新。
进度计数器给用户两个信息:
- 当前在第几页:第一个数字
- 总共多少页:第二个数字
在引导页中,这种进度表示法比"仅显示圆点指示器"更精确——用户不仅知道相对位置(第 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 轮播组件的使用方法。核心知识点包括:
- Swiper 基础 API:构造参数、index 绑定、loop 循环、interval 间隔
- SwiperController:
changeIndex()编程式翻页,支持跳转到任意页 - Indicator 指示器:
.dot()圆点样式 + 尺寸/颜色定制 - 自动播放控制:
autoPlay+loop+interval三件套,配合 Toggle 开关 - onChange 回调:页面切换时同步
currentIndex,驱动进度文字和按钮状态 - 导航按钮:上一页/下一页 + 边界禁用状态 + 动态颜色
Swiper 是移动应用中使用频率最高的组件之一。一个好的轮播体验不仅仅是"能左右滑动"——它需要清晰的进度指示、平滑的翻页动画、可控的自动播放和精确的编程式导航。ArkUI 的 Swiper 组件提供了这些能力的完整封装,让开发者可以将精力集中在卡片内容的设计上。
更多推荐



所有评论(0)