flutter轮播组件教程

简介

carousel_slider 是 Flutter 中一个功能强大的轮播图组件,支持自动播放、无限循环、自定义指示器等多种特性。本教程将详细介绍所有配置项和使用方法。

安装

pubspec.yaml 文件中添加依赖:

yaml 复制代码
dependencies:
  carousel_slider: ^4.2.1

然后运行 flutter pub get 安装依赖。

基础用法

最简单的轮播图

dart 复制代码
CarouselSlider(
  options: CarouselOptions(height: 400.0),
  items: [1,2,3,4,5].map((i) {
    return Builder(
      builder: (BuildContext context) {
        return Container(
          width: MediaQuery.of(context).size.width,
          margin: EdgeInsets.symmetric(horizontal: 5.0),
          decoration: BoxDecoration(
            color: Colors.amber
          ),
          child: Text('text $i', style: TextStyle(fontSize: 16.0),)
        );
      },
    );
  }).toList(),
)

API 文档

CarouselOptions

轮播图的所有配置选项通过 CarouselOptions 类进行设置。

参数 说明 类型 默认值
height 轮播图高度 double -
aspectRatio 轮播图宽高比,当设置此项时,height 将被忽略 double -
viewportFraction 每一页在视口中的占比,1.0 表示一页占满整个视口 double 0.9
initialPage 初始显示的页面索引 int 0
enableInfiniteScroll 是否启用无限滚动 bool true
reverse 是否反向滚动 bool false
autoPlay 是否自动播放 bool false
autoPlayInterval 自动播放间隔时间 Duration Duration(seconds: 3)
autoPlayAnimationDuration 自动播放动画持续时间 Duration Duration(milliseconds: 800)
autoPlayCurve 自动播放动画曲线 Curve Curves.fastOutSlowIn
enlargeCenterPage 是否放大当前页面 bool false
enlargeFactor 放大因子,当 enlargeCenterPage 为 true 时生效 double 0.3
scrollDirection 滚动方向 Axis Axis.horizontal
pauseAutoPlayOnTouch 触摸时是否暂停自动播放 bool true
pauseAutoPlayInFiniteScroll 在无限滚动模式下是否暂停自动播放 bool true
pauseAutoPlayOnManualNavigate 手动导航时是否暂停自动播放 bool true
pageSnapping 是否启用页面捕捉效果 bool true
height 轮播图高度 double -
aspectRatio 轮播图宽高比 double -
viewportFraction 每一页在视口中的占比 double 0.9
initialPage 初始显示的页面索引 int 0
enableInfiniteScroll 是否启用无限滚动 bool true
reverse 是否反向滚动 bool false
autoPlay 是否自动播放 bool false
autoPlayInterval 自动播放间隔时间 Duration Duration(seconds: 3)
autoPlayAnimationDuration 自动播放动画持续时间 Duration Duration(milliseconds: 800)
autoPlayCurve 自动播放动画曲线 Curve Curves.fastOutSlowIn
enlargeCenterPage 是否放大当前页面 bool false
enlargeFactor 放大因子 double 0.3
scrollDirection 滚动方向 Axis Axis.horizontal
pauseAutoPlayOnTouch 触摸时是否暂停自动播放 bool true
pauseAutoPlayInFiniteScroll 无限滚动模式下是否暂停自动播放 bool true
pauseAutoPlayOnManualNavigate 手动导航时是否暂停自动播放 bool true
pageSnapping 是否启用页面捕捉效果 bool true
onPageChanged 页面变化回调 Function(int, CarouselPageChangedReason) -
onScrolled 滚动回调 Function(double) -
clipBehavior 裁剪行为 Clip Clip.hardEdge

CarouselSlider

参数 说明 类型 默认值
options 轮播图配置选项 CarouselOptions 必填
items 轮播项列表 List 必填
carouselController 轮播图控制器 CarouselController? -

配置项详解

height

设置轮播图的高度。如果同时设置了 aspectRatio,则 height 会被忽略。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(height: 400.0),
  items: [...],
)

aspectRatio

设置轮播图的宽高比。当设置此项时,height 参数将被忽略。这个参数对于响应式设计很有用。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(aspectRatio: 16/9),
  items: [...],
)

viewportFraction

每一页在视口中的占比,默认为 0.9,表示每一页占据视口宽度的 90%。设置为 1.0 时,每一页将占满整个视口。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    viewportFraction: 1.0,
  ),
  items: [...],
)

initialPage

设置初始显示的页面索引,默认为 0。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    initialPage: 2,
  ),
  items: [...],
)

enableInfiniteScroll

是否启用无限滚动,默认为 true。当设置为 true 时,轮播图可以无限循环滚动;设置为 false 时,滚动到最后一页后无法继续滚动。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    enableInfiniteScroll: false,
  ),
  items: [...],
)

reverse

是否反向滚动,默认为 false。当设置为 true 时,轮播图将从右向左(或从下向上)滚动。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    reverse: true,
  ),
  items: [...],
)

autoPlay

是否自动播放,默认为 false。当设置为 true 时,轮播图将自动滚动。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
  ),
  items: [...],
)

autoPlayInterval

设置自动播放的间隔时间,默认为 3 秒。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    autoPlayInterval: Duration(seconds: 5),
  ),
  items: [...],
)

autoPlayAnimationDuration

设置自动播放动画的持续时间,默认为 800 毫秒。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    autoPlayAnimationDuration: Duration(milliseconds: 500),
  ),
  items: [...],
)

autoPlayCurve

设置自动播放动画的曲线,默认为 Curves.fastOutSlowIn

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    autoPlayCurve: Curves.easeInOut,
  ),
  items: [...],
)

enlargeCenterPage

是否放大当前页面,默认为 false。当设置为 true 时,当前页面会比其他页面大。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    enlargeCenterPage: true,
  ),
  items: [...],
)

enlargeFactor

设置放大因子,默认为 0.3。当 enlargeCenterPage 为 true 时,当前页面会放大这个比例。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    enlargeCenterPage: true,
    enlargeFactor: 0.5,
  ),
  items: [...],
)

scrollDirection

设置滚动方向,默认为水平方向 (Axis.horizontal)。可以设置为垂直方向 (Axis.vertical)。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    scrollDirection: Axis.vertical,
  ),
  items: [...],
)

pauseAutoPlayOnTouch

触摸时是否暂停自动播放,默认为 true。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    pauseAutoPlayOnTouch: false,
  ),
  items: [...],
)

pauseAutoPlayInFiniteScroll

在无限滚动模式下是否暂停自动播放,默认为 true。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    pauseAutoPlayInFiniteScroll: false,
  ),
  items: [...],
)

pauseAutoPlayOnManualNavigate

手动导航时是否暂停自动播放,默认为 true。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    pauseAutoPlayOnManualNavigate: false,
  ),
  items: [...],
)

pageSnapping

是否启用页面捕捉效果,默认为 true。当设置为 true 时,滚动会自动吸附到最近的页面。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    pageSnapping: false,
  ),
  items: [...],
)

onPageChanged

页面变化时的回调函数,接收两个参数:当前页面索引和页面变化原因。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    onPageChanged: (index, reason) {
      print("当前页面: $index, 变化原因: $reason");
    },
  ),
  items: [...],
)

onScrolled

滚动时的回调函数,接收当前滚动位置作为参数。

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    onScrolled: (value) {
      print("滚动位置: $value");
    },
  ),
  items: [...],
)

clipBehavior

设置裁剪行为,默认为 Clip.hardEdge

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    clipBehavior: Clip.antiAlias,
  ),
  items: [...],
)

CarouselController

CarouselController 允许你以编程方式控制轮播图的行为。

创建控制器

dart 复制代码
final CarouselController _controller = CarouselController();

使用控制器

dart 复制代码
CarouselSlider(
  options: CarouselOptions(height: 400.0),
  carouselController: _controller,
  items: [...],
)

控制器方法

方法 说明 参数
nextPage 切换到下一页 duration, curve
previousPage 切换到上一页 duration, curve
jumpToPage 跳转到指定页面 page
animateToPage 动画跳转到指定页面 page, duration, curve
startAutoPlay 开始自动播放 -
stopAutoPlay 停止自动播放 -
nextPage 示例
dart 复制代码
_controller.nextPage(
  duration: Duration(milliseconds: 300),
  curve: Curves.linear,
);
previousPage 示例
dart 复制代码
_controller.previousPage(
  duration: Duration(milliseconds: 300),
  curve: Curves.linear,
);
jumpToPage 示例
dart 复制代码
_controller.jumpToPage(2);
animateToPage 示例
dart 复制代码
_controller.animateToPage(
  2,
  duration: Duration(milliseconds: 300),
  curve: Curves.linear,
);
startAutoPlay 示例
dart 复制代码
_controller.startAutoPlay();
stopAutoPlay 示例
dart 复制代码
_controller.stopAutoPlay();

完整示例

下面是一个完整的示例,展示了如何使用 carousel_slider 创建一个带有自定义指示器的轮播图:

dart 复制代码
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';

class CarouselDemo extends StatefulWidget {
  @override
  _CarouselDemoState createState() => _CarouselDemoState();
}

class _CarouselDemoState extends State<CarouselDemo> {
  int _current = 0;
  final CarouselController _controller = CarouselController();

  final List<String> imgList = [
    'https://images.unsplash.com/photo-1520342868574-5fa3804e551c?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=6ff92caffcdd63681a35134a6770ed3b&auto=format&fit=crop&w=1951&q=80',
    'https://images.unsplash.com/photo-1522205408450-add114ad53fe?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=368f45b0888aeb0b7b08e3a1084d3ede&auto=format&fit=crop&w=1950&q=80',
    'https://images.unsplash.com/photo-1519125323398-675f0ddb6308?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=94a1e718d89ca60a6337a6008341ca50&auto=format&fit=crop&w=1950&q=80',
    'https://images.unsplash.com/photo-1523205771623-e0faa4d2813d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=89719a0d55dd05e2deae4120227e6efc&auto=format&fit=crop&w=1953&q=80',
    'https://images.unsplash.com/photo-1508700115892-45ecd05ae2ad?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bba1d701670aa4354a4c63a781298771&auto=format&fit=crop&w=1950&q=80',
    'https://images.unsplash.com/photo-1519985176271-adb1088fa94c?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=f0fbb19ed722a57174d0c6286b2a0ff1&auto=format&fit=crop&w=1950&q=80',
  ];

  @override
  Widget build(BuildContext context) {
    final List<Widget> imageSliders = imgList
        .map((item) => Container(
              child: Container(
                margin: EdgeInsets.all(5.0),
                child: ClipRRect(
                    borderRadius: BorderRadius.all(Radius.circular(5.0)),
                    child: Stack(
                      children: <Widget>[
                        Image.network(item, fit: BoxFit.cover, width: 1000.0),
                        Positioned(
                          bottom: 0.0,
                          left: 0.0,
                          right: 0.0,
                          child: Container(
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  Color.fromARGB(200, 0, 0, 0),
                                  Color.fromARGB(0, 0, 0, 0)
                                ],
                                begin: Alignment.bottomCenter,
                                end: Alignment.topCenter,
                              ),
                            ),
                            padding: EdgeInsets.symmetric(
                                vertical: 10.0, horizontal: 20.0),
                            child: Text(
                              'No. ${imgList.indexOf(item)} image',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 20.0,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                      ],
                    )),
              ),
            ))
        .toList();

    return Scaffold(
      appBar: AppBar(title: Text('Carousel Slider Demo')),
      body: Column(
        children: [
          CarouselSlider(
            items: imageSliders,
            carouselController: _controller,
            options: CarouselOptions(
                autoPlay: true,
                enlargeCenterPage: true,
                aspectRatio: 2.0,
                onPageChanged: (index, reason) {
                  setState(() {
                    _current = index;
                  });
                }),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: imgList.asMap().entries.map((entry) {
              return GestureDetector(
                onTap: () => _controller.animateToPage(entry.key),
                child: Container(
                  width: 12.0,
                  height: 12.0,
                  margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
                  decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: (Theme.of(context).brightness == Brightness.dark
                              ? Colors.white
                              : Colors.black)
                          .withOpacity(_current == entry.key ? 0.9 : 0.4)),
                ),
              );
            }).toList(),
          ),
        ],
      ),
    );
  }
}

高级用法

自定义指示器

你可以创建完全自定义的指示器,如下面的示例:

dart 复制代码
class CarouselWithIndicatorDemo extends StatefulWidget {
  @override
  _CarouselWithIndicatorDemoState createState() =>
      _CarouselWithIndicatorDemoState();
}

class _CarouselWithIndicatorDemoState extends State<CarouselWithIndicatorDemo> {
  int _current = 0;
  final CarouselController _controller = CarouselController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        CarouselSlider(
          items: imageSliders,
          carouselController: _controller,
          options: CarouselOptions(
              autoPlay: true,
              enlargeCenterPage: true,
              aspectRatio: 2.0,
              onPageChanged: (index, reason) {
                setState(() {
                  _current = index;
                });
              }),
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: imgList.asMap().entries.map((entry) {
            return GestureDetector(
              onTap: () => _controller.animateToPage(entry.key),
              child: Container(
                width: 12.0,
                height: 12.0,
                margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
                decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: (Theme.of(context).brightness == Brightness.dark
                            ? Colors.white
                            : Colors.black)
                        .withOpacity(_current == entry.key ? 0.9 : 0.4)),
              ),
            );
          }).toList(),
        ),
      ],
    );
  }
}

垂直轮播

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    aspectRatio: 16/9,
    viewportFraction: 0.8,
    initialPage: 0,
    enableInfiniteScroll: true,
    reverse: false,
    autoPlay: true,
    autoPlayInterval: Duration(seconds: 3),
    autoPlayAnimationDuration: Duration(milliseconds: 800),
    autoPlayCurve: Curves.fastOutSlowIn,
    enlargeCenterPage: true,
    enlargeFactor: 0.3,
    scrollDirection: Axis.vertical,
  ),
  items: [1,2,3,4,5].map((i) {
    return Builder(
      builder: (BuildContext context) {
        return Container(
          width: MediaQuery.of(context).size.width,
          margin: EdgeInsets.symmetric(vertical: 5.0),
          decoration: BoxDecoration(
            color: Colors.amber
          ),
          child: Text('text $i', style: TextStyle(fontSize: 16.0),)
        );
      },
    );
  }).toList(),
)

无限循环轮播

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    enableInfiniteScroll: true,
    autoPlay: true,
  ),
  items: [1,2,3,4,5].map((i) {
    return Builder(
      builder: (BuildContext context) {
        return Container(
          width: MediaQuery.of(context).size.width,
          margin: EdgeInsets.symmetric(horizontal: 5.0),
          decoration: BoxDecoration(
            color: Colors.amber
          ),
          child: Text('text $i', style: TextStyle(fontSize: 16.0),)
        );
      },
    );
  }).toList(),
)

自定义动画曲线

dart 复制代码
CarouselSlider(
  options: CarouselOptions(
    height: 400.0,
    autoPlay: true,
    autoPlayCurve: Curves.easeInOutCubic,
  ),
  items: [...],
)

多个轮播图

你可以在同一个页面中使用多个轮播图,每个轮播图都有自己的控制器:

dart 复制代码
class MultipleCarouselDemo extends StatefulWidget {
  @override
  _MultipleCarouselDemoState createState() => _MultipleCarouselDemoState();
}

class _MultipleCarouselDemoState extends State<MultipleCarouselDemo> {
  final CarouselController _controller1 = CarouselController();
  final CarouselController _controller2 = CarouselController();
  int _current1 = 0;
  int _current2 = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 第一个轮播图
        CarouselSlider(
          items: imageSliders1,
          carouselController: _controller1,
          options: CarouselOptions(
            autoPlay: true,
            enlargeCenterPage: true,
            aspectRatio: 2.0,
            onPageChanged: (index, reason) {
              setState(() {
                _current1 = index;
              });
            },
          ),
        ),
        // 第一个轮播图的指示器
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: imgList1.asMap().entries.map((entry) {
            return GestureDetector(
              onTap: () => _controller1.animateToPage(entry.key),
              child: Container(
                width: 12.0,
                height: 12.0,
                margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.blue.withOpacity(_current1 == entry.key ? 0.9 : 0.4),
                ),
              ),
            );
          }).toList(),
        ),
        SizedBox(height: 20),
        // 第二个轮播图
        CarouselSlider(
          items: imageSliders2,
          carouselController: _controller2,
          options: CarouselOptions(
            autoPlay: true,
            enlargeCenterPage: true,
            aspectRatio: 2.0,
            onPageChanged: (index, reason) {
              setState(() {
                _current2 = index;
              });
            },
          ),
        ),
        // 第二个轮播图的指示器
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: imgList2.asMap().entries.map((entry) {
            return GestureDetector(
              onTap: () => _controller2.animateToPage(entry.key),
              child: Container(
                width: 12.0,
                height: 12.0,
                margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.red.withOpacity(_current2 == entry.key ? 0.9 : 0.4),
                ),
              ),
            );
          }).toList(),
        ),
      ],
    );
  }
}

注意事项

  1. 当使用 aspectRatio 时,height 参数将被忽略。
  2. enableInfiniteScroll 设置为 true 时,轮播图可以无限循环滚动。
  3. 使用 CarouselController 可以以编程方式控制轮播图的行为。
  4. autoPlay 设置为 true 时,可以通过 pauseAutoPlayOnTouchpauseAutoPlayInFiniteScrollpauseAutoPlayOnManualNavigate 控制自动播放的暂停行为。
  5. enlargeCenterPage 设置为 true 时,可以通过 enlargeFactor 调整放大比例。

总结

carousel_slider 是一个功能强大且灵活的 Flutter 轮播图组件,通过合理配置 CarouselOptions 和使用 CarouselController,可以创建各种类型的轮播图效果。希望本教程能帮助你更好地理解和使用这个组件。

相关推荐
Hello__77772 小时前
开源鸿蒙 Flutter 实战|用户头像编辑功能全流程实现
flutter·开源·harmonyos
jiejiejiejie_3 小时前
Flutter for OpenHarmony 数据统计与用户行为分析萌系实战指南✨
flutter·华为·harmonyos
liulian09165 小时前
【Flutter for OpenHarmony第三方库】Flutter for OpenHarmony 数据统计与用户行为分析功能适配与实现指南
flutter·华为·学习方法·harmonyos
饭小猿人16 小时前
Flutter实现底部动画弹窗有两种方式
开发语言·前端·flutter
liulian091620 小时前
Flutter 跨平台路由与状态管理:go_router 与 Riverpod 的 OpenHarmony总结
flutter·华为·学习方法·harmonyos
liulian091621 小时前
Flutter for OpenHarmony 跨平台技术实战:flutter_animate 与 pull_to_refresh 库的鸿蒙化适配总结
flutter·华为·学习方法·harmonyos
IntMainJhy21 小时前
【flutter for open harmony】第三方库 Flutter 二维码生成的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos
jiejiejiejie_1 天前
Flutter for OpenHarmony 底部选项卡与多语言适配小记:让 App 更贴心的两次小升级✨
flutter·华为·harmonyos
jiejiejiejie_1 天前
Flutter for OpenHarmony 应用更新检测与萌系搜索功能实战小记✨
flutter·华为·harmonyos