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,可以创建各种类型的轮播图效果。希望本教程能帮助你更好地理解和使用这个组件。

相关推荐
liulian09161 天前
Flutter 网络状态与内容分享库:connectivity_plus 与 share_plus 的 OpenHarmony 适配指南
网络·flutter
KKei16381 天前
Flutter for OpenHarmony 学习视频播放器技术文章
学习·flutter·华为·音视频·harmonyos
KKei16381 天前
Flutter for OpenHarmony 健身计划与运动打卡APP
flutter·华为·harmonyos
KKei16381 天前
Flutter for OpenHarmony 在线考试与自测系统APP技术文章
flutter·华为·harmonyos
liulian09161 天前
Flutter 依赖注入与设备信息库:get_it 与 device_info_plus 的 OpenHarmony 适配指南
flutter
KKei16381 天前
Flutter for OpenHarmony学习目标追踪应用技术文章
学习·flutter·华为·harmonyos
KKei16381 天前
Flutter for OpenHarmony 编程技能树APP技术文章
flutter·华为·harmonyos