Carousel Slider 轮播组件教程
简介
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(),
),
],
);
}
}
注意事项
- 当使用
aspectRatio时,height参数将被忽略。 enableInfiniteScroll设置为 true 时,轮播图可以无限循环滚动。- 使用
CarouselController可以以编程方式控制轮播图的行为。 - 当
autoPlay设置为 true 时,可以通过pauseAutoPlayOnTouch、pauseAutoPlayInFiniteScroll和pauseAutoPlayOnManualNavigate控制自动播放的暂停行为。 enlargeCenterPage设置为 true 时,可以通过enlargeFactor调整放大比例。
总结
carousel_slider 是一个功能强大且灵活的 Flutter 轮播图组件,通过合理配置 CarouselOptions 和使用 CarouselController,可以创建各种类型的轮播图效果。希望本教程能帮助你更好地理解和使用这个组件。