SwiperController 编程式控制翻页与 showNext

前言

在 Swiper 轮播组件中,除了用户手势滑动翻页,还经常需要编程式控制 翻页。SwiperController 提供了 showNext()showPrevious() 等 API,用于在代码中控制轮播的切换。

"海风日记"的引导页通过 SwiperController 实现了"下一步"按钮的编程式翻页,以及"跳过"按钮的直接跳转。本文将从源码出发,深入讲解 SwiperController 的完整用法。


一、SwiperController 概述

1.1 创建控制器

typescript 复制代码
private swiperController: SwiperController = new SwiperController()

1.2 绑定到 Swiper

typescript 复制代码
Swiper(this.swiperController) {
  // 页面内容
}

1.3 API 方法

方法 说明 参数
showNext() 切换到下一页
showPrevious() 切换到上一页
finishAnimation() 结束当前动画

二、编程式翻页的三种方式

2.1 showNext / showPrevious

typescript 复制代码
// 切换到下一页
Button('下一步')
  .onClick(() => {
    this.swiperController.showNext()
  })

// 切换到上一页
Button('上一步')
  .onClick(() => {
    this.swiperController.showPrevious()
  })

2.2 通过 onChange 同步状态

typescript 复制代码
@State currentIndex: number = 0

Swiper(this.swiperController)
  .onChange((index: number) => {
    this.currentIndex = index  // 同步当前索引
  })

2.3 条件判断翻页

typescript 复制代码
Button(this.currentIndex === 2 ? '立即开始' : '下一步')
  .onClick(() => {
    if (this.currentIndex === 2) {
      // 最后一页:跳转到首页
      router.replaceUrl({ url: 'pages/Index' })
    } else {
      // 翻到下一页
      this.swiperController.showNext()
    }
  })

三、SwiperController 的完整交互

3.1 引导页的翻页逻辑

typescript 复制代码
@Entry
@Component
struct OnboardingPage {
  @State currentIndex: number = 0
  private swiperController: SwiperController = new SwiperController()

  build() {
    Stack() {
      Column() {
        Swiper(this.swiperController) {
          ForEach(PAGES, (page: OnboardingPageData, idx: number) => {
            this.buildPage(page, idx)
          })
        }
        .layoutWeight(1)
        .indicator(false)
        .loop(false)
        .onChange((index: number) => {
          this.currentIndex = index
        })

        // 底部固定区域
        Column({ space: 16 }) {
          // 分页圆点
          this.pageDots()

          // 底部按钮
          Button(this.currentIndex === 2 ? '立即开始' : '下一步')
            .width('85%').height(52)
            .fontSize(17).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)
            .backgroundColor(COLOR_PRIMARY).borderRadius(26)
            .onClick(() => {
              if (this.currentIndex === 2) {
                router.replaceUrl({ url: 'pages/Index' })
              } else {
                this.swiperController.showNext()
              }
            })
        }
        .padding({ top: 16, bottom: 40 })
        .backgroundColor(PAGES[this.currentIndex].bg)
      }

      // 跳过按钮
      Button('跳过')
        .position({ top: 52, right: 20 })
        .onClick(() => { router.replaceUrl({ url: 'pages/Index' }) })
    }
  }
}

3.2 用户操作的所有可能路径

复制代码
用户操作路径 1(正常流程):
  第 1 页 → 点击"下一步" → 第 2 页 → 点击"下一步" → 第 3 页 → 点击"立即开始" → 首页

用户操作路径 2(跳过):
  任意页 → 点击"跳过" → 首页

四、SwiperController 与手势的交互

4.1 手势与编程式控制的优先级

操作方式 触发方式 优先级
手势滑动 用户手指滑动 用户主动操作
编程式控制 showNext() / showPrevious() 代码控制

4.2 禁用手势

如果需要完全禁用用户手势,只允许编程式控制:

typescript 复制代码
Swiper(this.swiperController) {
  // 页面内容
}
.disableSwipe(true)  // 禁用滑动

4.3 手势与编程式控制的对比

控制方式 适用场景 优点 缺点
手势滑动 浏览型内容 自然直观 无法精确控制
编程式控制 引导页、表单 精确控制 需要额外代码

五、SwiperController 的典型应用场景

5.1 引导页

typescript 复制代码
// 最后一页才显示"开始"按钮
Button(this.currentIndex === 2 ? '立即开始' : '下一步')
  .onClick(() => {
    if (this.currentIndex === 2) {
      router.replaceUrl({ url: 'pages/Index' })
    } else {
      this.swiperController.showNext()
    }
  })

5.2 图片查看器

typescript 复制代码
// 上一张 / 下一张按钮
Row() {
  Button('上一张')
    .onClick(() => { this.swiperController.showPrevious() })

  Button('下一张')
    .onClick(() => { this.swiperController.showNext() })
}

5.3 表单分步

typescript 复制代码
// 分步表单的下一步/上一步
Button('上一步')
  .enabled(this.currentIndex > 0)  // 第一页禁用
  .onClick(() => { this.swiperController.showPrevious() })

Button('下一步')
  .enabled(this.currentIndex < 2)  // 最后一页禁用
  .onClick(() => { this.swiperController.showNext() })

六、SwiperController 的动画控制

6.1 动画时长

typescript 复制代码
Swiper(this.swiperController)
  .duration(400)  // 切换动画时长 400ms

6.2 动画曲线

typescript 复制代码
Swiper(this.swiperController)
  .curve(Curve.EaseInOut)  // 缓入缓出曲线

6.3 动画完成回调

typescript 复制代码
Swiper(this.swiperController)
  .onAnimationStart(() => {
    console.info('动画开始')
  })
  .onAnimationEnd(() => {
    console.info('动画结束')
  })

七、常见问题与排查

7.1 showNext 不生效

问题:调用 showNext() 后页面没有切换。

原因 :已经到达最后一页,且 loopfalse

解决方案:在调用前检查当前索引:

typescript 复制代码
if (this.currentIndex < totalPages - 1) {
  this.swiperController.showNext()
}

7.2 控制器未绑定

问题:SwiperController 方法无效。

原因:控制器未传递给 Swiper 组件。

解决方案

typescript 复制代码
Swiper(this.swiperController)  // 必须传递控制器

总结

本文通过"海风日记"引导页的源码,深入讲解了 SwiperController 的完整用法:

  1. SwiperController 基础:创建、绑定、API 方法
  2. 编程式翻页:showNext / showPrevious 的使用
  3. 交互逻辑:条件判断、按钮文字切换、跳过功能
  4. 手势控制:禁用滑动、手势与编程式控制的对比
  5. 典型场景:引导页、图片查看器、分步表单
  6. 动画控制:时长、曲线、回调

下一篇文章将深入讲解 indicator 自定义分页圆点动画与交互,敬请期待。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

相关推荐
hold?fish:palm13 小时前
RDB全量快照备份
c++·redis·后端
LucianaiB14 小时前
我把刘备一生做成了可播放的高德地图,还把整套方法封装成了 Skill
后端
Reart14 小时前
操作系统实验哈工大lab2——系统调用
后端·操作系统
IT_陈寒14 小时前
React useEffect依赖数组中埋的坑,这次终于让我逮到了
前端·人工智能·后端
扎Zn了老Fe15 小时前
MyBatis-Plus必知必会:告别低效CRUD,高效开发持久层
后端·mybatis
用户4603812919415 小时前
终于知道AQS是啥东西了
后端
神奇小汤圆16 小时前
SpringBoot 相关的 Skills 全景指南
后端
神奇小汤圆17 小时前
高性能进程内队列 BufferQueue 1.0 版本发布
后端
爸爸61917 小时前
空数据状态与引导:多维度 UI 提示设计
后端